关于 azure-search-documents-ts
这是一项使用 Azure AI Search SDK 构建搜索应用的 TypeScript 技能,涵盖全文、向量、混合和语义搜索,以及索引与文档操作。
主要功能
- 01创建含向量字段的索引
- 02上传和更新文档
- 03全文与向量搜索
- 04混合与语义搜索
- 05筛选、分面、自动补全和建议
- 06批量索引操作
适用场景
- 01创建产品搜索索引
- 02索引并更新文档集合
- 03组合文本与向量查询
- 04筛选结果并获取分面
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-search-documents-ts安装后在 Claude Code 中输入/azure-search-documents-ts确认已加载。
详细介绍
Azure AI Search SDK for TypeScript
使用向量、混合和语义搜索功能构建搜索应用。
安装
npm install @azure/search-documents @azure/identity
环境变量
AZURE_SEARCH_ENDPOINT=https://<service-name>.search.windows.net
AZURE_SEARCH_INDEX_NAME=my-index
AZURE_SEARCH_ADMIN_KEY=<admin-key> # Optional if using Entra ID
身份验证
import { SearchClient, SearchIndexClient } from "@azure/search-documents";
import { DefaultAzureCredential } from "@azure/identity";
const endpoint = process.env.AZURE_SEARCH_ENDPOINT!;
const indexName = process.env.AZURE_SEARCH_INDEX_NAME!;
const credential = new DefaultAzureCredential();
// For searching
const searchClient = new SearchClient(endpoint, indexName, credential);
// For index management
const indexClient = new SearchIndexClient(endpoint, credential);
版本、架构和授权
代码片段是包含占位符的独立片段,并非可直接运行的完整程序。使用前请核实已安装的 SDK 类型、实际索引架构以及嵌入模型和维度。请根据经过身份验证的身份在服务端设置文档安全筛选器;切勿信任客户端提供的筛选器来实施访问控制。创建或更新索引,以及上传或删除记录,都需要对目标资源具有精确的授权,并且可能改变付费服务的状态。
核心工作流
创建包含向量字段的索引
import { SearchIndex, SearchField, VectorSearch } from "@azure/search-documents";
const index: SearchIndex = {
name: "products",
fields: [
{ name: "id", type: "Edm.String", key: true },
{ name: "title", type: "Edm.String", searchable: true },
{ name: "description", type: "Edm.String", searchable: true },
{ name: "category", type: "Edm.String", filterable: true, facetable: true },
{
name: "embedding",
type: "Collection(Edm.Single)",
searchable: true,
vectorSearchDimensions: 1536,
vectorSearchProfileName: "vector-profile",
},
],
vectorSearch: {
algorithms: [
{ name: "hnsw-algorithm", kind: "hnsw" },
],
profiles: [
{ name: "vector-profile", algorithmConfigurationName: "hnsw-algorithm" },
],
},
};
await indexClient.createOrUpdateIndex(index);
索引文档
const documents = [
{ id: "1", title: "Widget", description: "A useful widget", category: "Tools", embedding: [...] },
{ id: "2", title: "Gadget", description: "A cool gadget", category: "Electronics", embedding: [...] },
];
const result = await searchClient.uploadDocuments(documents);
const failures = result.results.filter((item) => !item.succeeded);
if (failures.length) throw new Error(`Indexing failed for ${failures.length} documents`);
console.log(`Indexed ${result.results.length} documents`);
全文搜索
const results = await searchClient.search("widget", {
select: ["id", "title", "description"],
filter: "category eq 'Tools'",
orderBy: ["title asc"],
top: 10,
});
for await (const result of results.results) {
console.log(`${result.document.title}: ${result.score}`);
}
向量搜索
const queryVector = await getEmbedding("useful tool"); // Your embedding function
const results = await searchClient.search("*", {
vectorSearchOptions: {
queries: [
{
kind: "vector",
vector: queryVector,
fields: ["embedding"],
kNearestNeighborsCount: 10,
},
],
},
select: ["id", "title", "description"],
});
for await (const result of results.results) {
console.log(`${result.document.title}: ${result.score}`);
}
混合搜索(文本 + 向量)
const queryVector = await getEmbedding("useful tool");
const results = await searchClient.search("tool", {
vectorSearchOptions: {
queries: [
{
kind: "vector",
vector: queryVector,
fields: ["embedding"],
kNearestNeighborsCount: 50,
},
],
},
select: ["id", "title", "description"],
top: 10,
});
语义搜索
// Index must have semantic configuration
const index: SearchIndex = {
name: "products",
fields: [...],
semanticSearch: {
configurations: [
{
name: "semantic-config",
prioritizedFields: {
titleField: { name: "title" },
contentFields: [{ name: "description" }],
},
},
],
},
};
// Search with semantic ranking
const results = await searchClient.search("best tool for the job", {
queryType: "semantic",
semanticSearchOptions: {
configurationName: "semantic-config",
captions: { captionType: "extractive" },
answers: { answerType: "extractive", count: 3 },
},
select: ["id", "title", "description"],
});
for await (const result of results.results) {
console.log(`${result.document.title}`);
console.log(` Caption: ${result.captions?.[0]?.text}`);
console.log(` Reranker Score: ${result.rerankerScore}`);
}
筛选和分面
// Filter syntax
const results = await searchClient.search("*", {
filter: "category eq 'Electronics' and price lt 100",
facets: ["category,count:10", "brand"],
});
// Access facets
for (const [facetName, facetResults] of Object.entries(results.facets || {})) {
console.log(`${facetName}:`);
for (const facet of facetResults) {
console.log(` ${facet.value}: ${facet.count}`);
}
}
自动补全和建议
// Create suggester in index
const index: SearchIndex = {
name: "products",
fields: [...],
suggesters: [
{ name: "sg", sourceFields: ["title", "description"] },
],
};
// Autocomplete
const autocomplete = await searchClient.autocomplete("wid", "sg", {
mode: "twoTerms",
top: 5,
});
// Suggestions
const suggestions = await searchClient.suggest("wid", "sg", {
select: ["title"],
top: 5,
});
批量操作
// Batch upload, merge, delete
const batch = [
{ upload: { id: "1", title: "New Item" } },
{ merge: { id: "2", title: "Updated Title" } },
{ delete: { id: "3" } },
];
const result = await searchClient.indexDocuments({ actions: batch });
关键类型
import {
SearchClient,
SearchIndexClient,
SearchIndexerClient,
SearchIndex,
SearchField,
SearchOptions,
VectorSearch,
SemanticSearch,
SearchIterator,
} from "@azure/search-documents";
最佳实践
- 使用混合搜索 - 结合向量和文本,获得最佳结果
- 启用语义排序 - 提高自然语言查询的相关性
- 批量上传文档 - 使用包含多个文档的数组调用
uploadDocuments,而非逐个上传 - 使用筛选器保障安全 - 使用筛选器实现文档级安全控制
- 增量索引 - 使用
mergeOrUploadDocuments进行更新 - 监控查询性能 - 在生产环境中谨慎使用
includeTotalCount: true
适用场景
当任务符合概述中描述的工作流或操作时,可使用此技能。
限制
- 仅当任务明确符合上述范围时,才使用此技能。
- 不要将输出视为针对特定环境进行验证、测试或专家审查的替代品。
- 如果缺少必需的输入、权限、安全边界或成功标准,请暂停并要求澄清。
评论
支持 Markdown