在本教程中,为写入一个Azure AI 搜索索引的 DOCX、JSON 和 CSV 内容配置独立的 blob 索引器。 可空联合架构使每个管道都能填充其负责的字段,同时让应用程序能够统一查询所有格式。 当索引器具有兼容的字段映射并面向同一索引时,可以将此模式扩展到其他兼容的索引器类型。 本教程仅演示并验证文件夹范围的 Blob 索引器。
在本教程中,你将了解:
- 在单独的 Blob 文件夹中准备 DOCX、JSON 和 CSV 示例数据
- 创建联合架构索引和三个文件夹范围的 Blob 数据源
- 使用不同的分析和扩充路径配置三个索引器
- 运行索引器并验证组合关键字、矢量和混合结果
- 查看内容所有权、故障排除和清理做法
Important
Azure内容理解技能中的语义分块是 2026-08-01-preview REST API 的一部分。 没有语义分块的多索引器模式、索引投影和内容理解技能已正式发布。 但是,为了保持一致性,本教程在所有请求中使用 2026-08-01-preview。
这些特性和功能是 2026-08-01 预览版 REST API 的一部分。 2026-08-01-preview 已作为你的 Azure 订阅的一部分许可给你使用,并受 Microsoft Product Terms、Microsoft Products and Services Data Protection Addendum(“DPA”)和 Supplemental Terms of Use for Azure Previews 中适用于“预览版”的条款约束。
2026-08-01-preview 版本支持连接到其他 Microsoft 服务和第三方服务。 使用这些服务受其各自的条款的约束,可能会导致数据处理或存储超出Azure符合性边界,以及流入Azure符合性边界的数据。
您有责任管理您的数据是否流出贵组织的合规和地理边界之外,以及由此产生的任何相关影响。 确保已准备好适当的权限、边界和审批。
你负责仔细查看和测试在特定用例上下文中生成的应用程序,并做出所有适当的决策和自定义。 此责任包括实施自己的负责任的 AI 缓解措施,例如元系统、内容筛选器或其他安全系统,并确保应用程序满足适当的质量、可靠性、安全性和可信度标准。
先决条件
一份 Azure 订阅。 免费创建一个。
具有系统分配的托管标识的Azure AI 搜索服务。 在“搜索服务设置密钥>页上,将 API 访问控制设置为“两者”,以便服务接受Microsoft Entra ID持有者令牌或 API 密钥。 此设置可在本教程中启用持有者令牌请求,而无需中断使用 API 密钥的现有客户端。 仅当不再需要基于密钥的身份验证时,才选择基于 角色的访问控制 。 有关详细信息,请参阅 “启用基于角色的访问控制”。
用户帐户必须在搜索服务上具有 搜索服务参与者、 搜索索引数据参与者和 搜索索引数据读取者 角色。 这些角色授权在整个教程中使用持有者令牌发送的管理和查询操作。 有关详细信息,请参阅 通过角色连接到 Azure AI 搜索。 如果请求同时包含持有者令牌和 API 密钥,则 API 密钥优先。
具有 Blob 容器 的 Azure 存储帐户。 在容器中创建
docx、json和csv文件夹。 将存储帐户范围内的 存储 Blob 数据读取者 角色分配给搜索服务的托管标识。 你的用户帐户需要在存储帐户范围内具有 Storage Blob Data Contributor 角色,才能上传示例文件。Azure CLI和可以发送经过身份验证的请求的 REST 客户端。 运行
az login,选择包含你的搜索服务的订阅,并为 Azure AI 搜索作用域请求获取 Bearer 令牌:az account get-access-token --scope https://search.azure.cn/.default --query accessToken --output tsv将返回的令牌复制到本教程中每个
Authorization: Bearer <search-access-token>标头使用的<search-access-token>占位符内。 访问令牌过期,因此,如果收到身份验证错误,请请求另一个令牌。 在发送请求之前,请替换所有其他 尖括号占位符 。
占位符引用
本教程使用以下占位符:
| 占位符 | Value |
|---|---|
<search-endpoint> |
https://<search-service-name>.search.azure.cn |
<search-access-token> |
Azure CLI 返回的 Azure AI 搜索 访问令牌 |
<storage-resource-id> |
/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Storage/storageAccounts/<storage-account-name> |
<container-name> |
你的 blob 容器的名称 |
<storage-account-name> |
你的存储帐户名称 |
查看体系结构
三个 blob 索引器单独写入同一索引。 当多个索引器具有兼容的字段映射并面向同一索引时,可以应用常规设计,但本教程演示并仅验证文件夹范围的 Blob 索引器。
sourceType不是 Azure AI 搜索 的系统字段。 这是一个由文章定义的鉴别器,JSON 和 CSV 源记录会直接填充该字段,而 DOCX 技能集会在扩充过程中添加该字段。 Azure AI 搜索不推断哪个索引器编写了文档。
| 管道 | 源形状 | 索引路径 | 矢量行为 |
|---|---|---|---|
| DOCX | 一个较短的 .docx 文件 |
内容理解语义分块(预览)、常量 sourceType 分配、嵌入技能以及索引投影 |
已填充 |
| JSON | JSON 数组中的两个对象 | 直接字段映射 | 有意设为 null |
| CSV | 带有第一行标题的两行 | 直接字段映射和嵌入技能 | 已填充 |
如果示例 DOCX 生成一个区块,则示例结果包含五个搜索文档:一个 DOCX 投影子文档、两个 JSON 产品和两个 CSV 票证。 这四个直接索引的文档(2 JSON + 2 CSV)从源数据获取密钥。 DOCX 子项从索引投影中获得生成的键。 较长或结构更复杂的文档可能会生成多个投影子项。
Warning
为每个直接建立索引的源赋予全局唯一的文档键值,例如以 json_ 和 csv_ 为前缀的值。 索引器使用文档更新语义:当两个写入操作具有相同的键时,可以合并或覆盖字段。 冲突可能会导致生成一个存在不安全混合所有权的文档。
共享索引包含以下字段:
-
id、parentId、sourceType、content、contentVector、sourceUri、title和lastModified。 - 可为空的格式特定字段:
category、price、status和priority。
该 id 字段是索引键字段。 其 keyword 分析器将每个标识符保留为一个确切值。 JSON 和 CSV 记录提供唯一的文档键,而索引投影则生成 DOCX 子键。 当源内容或投影区块边界发生更改时,生成的子密钥可能会更改,因此不要预测或保留有关其值的假设。
准备示例文件
每个索引器从其关联的文件夹中读取一种格式。 为每个文件夹创建一个小文件,以便每个管道都有可供建立索引的内容,并能在本教程后续部分从共享索引中进行查询。
准备示例文件:
在
docx文件夹中,上传一个名为search-overview.docx的小文件。 添加标题Search overview和此一句段落:Azure AI 搜索 supports keyword and vector search over indexed content.短文档通常生成一个语义区块,但区块计数取决于文档结构。在
json文件夹中,使用此双元素数组上传products.json:[ { "id": "json_product_001", "sourceType": "json", "content": "Compact wireless keyboard for shared workspaces.", "sourceUri": "https://<storage-account-name>.blob.core.chinacloudapi.cn/<container-name>/json/products.json#product-001", "title": "Compact wireless keyboard", "lastModified": "2026-08-07T00:00:00Z", "category": "Accessories", "price": 49.99 }, { "id": "json_product_002", "sourceType": "json", "content": "Adjustable monitor stand with cable management.", "sourceUri": "https://<storage-account-name>.blob.core.chinacloudapi.cn/<container-name>/json/products.json#product-002", "title": "Adjustable monitor stand", "lastModified": "2026-08-07T00:00:00Z", "category": "Office", "price": 89.50 } ]在
csv文件夹中,使用以下两行上传tickets.csv:id,sourceType,content,sourceUri,title,lastModified,status,priority csv_ticket_001,csv,"Search results omit a recently added product.","https://<storage-account-name>.blob.core.chinacloudapi.cn/<container-name>/csv/tickets.csv#ticket-001","Missing product",2026-08-07T00:00:00Z,open,high csv_ticket_002,csv,"A synonym rule needs review before deployment.","https://<storage-account-name>.blob.core.chinacloudapi.cn/<container-name>/csv/tickets.csv#ticket-002","Review synonym rule",2026-08-07T00:00:00Z,pending,medium前缀
json_和csv_使直接索引的文档键值在两个管道之间保持唯一。验证容器中是否存在所有三个 Blob:
az storage blob list \ --account-name <storage-account-name> \ --container-name <container-name> \ --auth-mode login \ --query "[].name" \ --output tsvReference:az storage blob list (Azure CLI)
预期输出:
csv/tickets.csv docx/search-overview.docx json/products.json如果输出未列出所有三个文件,请验证是否已将每个文件上传到正确的文件夹路径。
创建联合架构索引
创建一个接受所有三个文档形状的索引。 管道未填充的字段保留为 null。 矢量化器在查询时将查询文本转换为向量,而这两个技能组都使用相同的嵌入模型来生成索引时的向量。
若要创建联合架构索引,请执行以下命令:
发送创建请求:
POST <search-endpoint>/indexes?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "multi-source-index", "fields": [ { "name": "id", "type": "Edm.String", "key": true, "searchable": true, "filterable": true, "retrievable": true, "analyzer": "keyword" }, { "name": "parentId", "type": "Edm.String", "filterable": true, "retrievable": true }, { "name": "sourceType", "type": "Edm.String", "filterable": true, "facetable": true, "retrievable": true }, { "name": "content", "type": "Edm.String", "searchable": true, "retrievable": true }, { "name": "contentVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "content-vector-profile" }, { "name": "sourceUri", "type": "Edm.String", "filterable": true, "retrievable": true }, { "name": "title", "type": "Edm.String", "searchable": true, "retrievable": true }, { "name": "lastModified", "type": "Edm.DateTimeOffset", "filterable": true, "sortable": true, "retrievable": true }, { "name": "category", "type": "Edm.String", "filterable": true, "facetable": true, "retrievable": true }, { "name": "price", "type": "Edm.Double", "filterable": true, "sortable": true, "retrievable": true }, { "name": "status", "type": "Edm.String", "filterable": true, "facetable": true, "retrievable": true }, { "name": "priority", "type": "Edm.String", "filterable": true, "facetable": true, "retrievable": true } ], "vectorSearch": { "algorithms": [ { "name": "content-hnsw", "kind": "hnsw", "hnswParameters": { "metric": "cosine", "m": 4, "efConstruction": 400, "efSearch": 500 } } ], "profiles": [ { "name": "content-vector-profile", "algorithm": "content-hnsw", "vectorizer": "content-azure-openai-vectorizer" } ], "vectorizers": [ { "name": "content-azure-openai-vectorizer", "kind": "azureOpenAI", "azureOpenAIParameters": { "resourceUri": "<resource-endpoint>", "deploymentId": "<embedding-deployment-name>", "modelName": "text-embedding-3-small" } } ] } }Reference:Create Index (REST API)
响应返回具有完整索引定义的 HTTP
201 Created。验证是否已创建索引:
GET <search-endpoint>/indexes/multi-source-index?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>Reference:Get Index (REST API)
响应包含
"name": "multi-source-index"和 12 个字段。 确认fields数组长度等于 12,并且vectorSearch部分包含content-azure-openai-vectorizer。
创建三个文件夹范围的数据源
为每个 Blob 文件夹创建单独的数据源。 这三个定义都可以使用相同的存储连接和容器。 该值 container.query 将每个数据源限制为一个虚拟文件夹。 例如, "query": "docx" 将 DOCX 数据源限制为文件夹下的 docx Blob。
每个索引器还将 indexedFileNameExtensions 用作文件类型允许列表。 文件夹查询和扩展允许列表是独立的筛选器:数据源限制索引器枚举的文件夹,以及索引器配置限制该文件夹中的文件类型符合条件。 此示例不需要 excludedFileNameExtensions ,因为每个允许列表只包含一个扩展。
要创建这三个文件夹作用域的数据源:
创建 DOCX 数据源:
POST <search-endpoint>/datasources?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "docx-blob-datasource", "type": "azureblob", "credentials": { "connectionString": "ResourceId=<storage-resource-id>;" }, "container": { "name": "<container-name>", "query": "docx" } }响应返回 HTTP
201 Created。创建 JSON 数据源:
POST <search-endpoint>/datasources?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "json-blob-datasource", "type": "azureblob", "credentials": { "connectionString": "ResourceId=<storage-resource-id>;" }, "container": { "name": "<container-name>", "query": "json" } }响应返回 HTTP
201 Created。创建 CSV 数据源:
POST <search-endpoint>/datasources?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "csv-blob-datasource", "type": "azureblob", "credentials": { "connectionString": "ResourceId=<storage-resource-id>;" }, "container": { "name": "<container-name>", "query": "csv" } }响应返回 HTTP
201 Created。
验证所有三个数据源是否存在:
GET <search-endpoint>/datasources?api-version=2026-08-01-preview
Authorization: Bearer <search-access-token>
Reference:List Data Sources (REST API)
响应value数组包含docx-blob-datasource和 json-blob-datasourcecsv-blob-datasource。 如果缺少任何项目,请检查相应的创建步骤是否有误。
配置 DOCX 管道
DOCX 管道将技能集与索引器配对。 技能集使用语义分块(预览),分配 docx 判别器,为每个分块生成嵌入,并将每个子项投影到共享索引中。 索引器将该技能集绑定到 docx-blob-datasource,使用 allowSkillsetToReadFileData 读取文件,并对每个 blob 运行该技能集。
若要配置 DOCX 管道,请执行以下操作:
创建技能集:
POST <search-endpoint>/skillsets?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "docx-semantic-skillset", "description": "Chunk and vectorize DOCX files for the shared index.", "skills": [ { "@odata.type": "#Microsoft.Skills.Util.ContentUnderstandingSkill", "name": "docx-content-understanding", "context": "/document", "chunkingProperties": { "method": "semantic", "unit": "tokens", "maximumLength": 500 }, "inputs": [ { "name": "file_data", "source": "/document/file_data" } ], "outputs": [ { "name": "text_sections", "targetName": "text_sections" } ] }, { "@odata.type": "#Microsoft.Skills.Util.ConditionalSkill", "name": "docx-source-type", "context": "/document/text_sections/*", "inputs": [ { "name": "condition", "source": "= true" }, { "name": "whenTrue", "source": "= 'docx'" }, { "name": "whenFalse", "source": "= null" } ], "outputs": [ { "name": "output", "targetName": "source_type" } ] } ], "indexProjections": { "selectors": [ { "targetIndexName": "multi-source-index", "parentKeyFieldName": "parentId", "sourceContext": "/document/text_sections/*", "mappings": [ { "name": "sourceType", "source": "/document/text_sections/*/source_type" }, { "name": "content", "source": "/document/text_sections/*/content" }, { "name": "contentVector", "source": "/document/text_sections/*/content_vector" }, { "name": "sourceUri", "source": "/document/metadata_storage_path" }, { "name": "title", "source": "/document/metadata_storage_name" }, { "name": "lastModified", "source": "/document/metadata_storage_last_modified" } ] } ], "parameters": { "projectionMode": "skipIndexingParentDocuments" } } }响应返回 HTTP
201 Created。条件技能既不选择也不排除 Blob 对象。 文件选择在技能集运行之前就已经通过
container.query和indexedFileNameExtensions完成了。 它的恒为 true 的条件仅在每个投影块上将常量值docx赋给sourceType。验证是否已创建技能集:
GET <search-endpoint>/skillsets/docx-semantic-skillset?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>响应包含
"name": "docx-semantic-skillset",以及skills数组中的三个技能。创建 DOCX 索引器:
POST <search-endpoint>/indexers?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "docx-indexer", "dataSourceName": "docx-blob-datasource", "targetIndexName": "multi-source-index", "skillsetName": "docx-semantic-skillset", "parameters": { "batchSize": 1, "configuration": { "dataToExtract": "contentAndMetadata", "parsingMode": "default", "indexedFileNameExtensions": ".docx", "allowSkillsetToReadFileData": true } }, "fieldMappings": [], "outputFieldMappings": [] }Reference:Create Indexer (REST API)
响应返回 HTTP
201 Created。 索引器会自动启动其第一次运行。索引投影创建
id和parentId。 不要在投影选择器中映射任一字段。检查索引器的状态:
GET <search-endpoint>/indexers/docx-indexer/status?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>等待
lastResult.status显示success,并确认lastResult.itemsFailed为0。 如果状态显示inProgress,请等待 30 秒,然后再次检查。 你将在本教程的后续内容中,通过查询索引来验证投影生成的 DOCX 输出。
配置 JSON 管道
JSON 管道单独使用索引器,而无需技能集。 索引器为每个数组元素创建一个搜索文档,直接映射源端拥有的键和其他字段,并有意将 contentVector 保留为 null。 矢量查询排除这些文档,而全文查询和筛选查询仍可返回它们。
配置 JSON 管道:
创建 JSON 索引器:
POST <search-endpoint>/indexers?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "json-indexer", "dataSourceName": "json-blob-datasource", "targetIndexName": "multi-source-index", "parameters": { "configuration": { "parsingMode": "jsonArray", "indexedFileNameExtensions": ".json" } }, "fieldMappings": [ { "sourceFieldName": "/id", "targetFieldName": "id" }, { "sourceFieldName": "/sourceType", "targetFieldName": "sourceType" }, { "sourceFieldName": "/content", "targetFieldName": "content" }, { "sourceFieldName": "/sourceUri", "targetFieldName": "sourceUri" }, { "sourceFieldName": "/title", "targetFieldName": "title" }, { "sourceFieldName": "/lastModified", "targetFieldName": "lastModified" }, { "sourceFieldName": "/category", "targetFieldName": "category" }, { "sourceFieldName": "/price", "targetFieldName": "price" } ], "outputFieldMappings": [] }参考:创建索引器(REST API)、 索引 JSON Blob 和文件,以及 定义字段映射
响应返回 HTTP
201 Created。 索引器会自动启动其第一次运行。验证索引器是否处理了这两条记录:
GET <search-endpoint>/indexers/json-indexer/status?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>等待
lastResult.status显示success,并确认lastResult.itemsFailed为0。 如果状态显示inProgress,请等待 15 秒,然后再次检查。 您将在本教程稍后通过查询该索引来验证这两条 JSON 记录。
配置 CSV 管道
CSV 管道将技能集与索引器配对。 索引器为每一行创建一个搜索文档,直接映射源端键和其他字段,并将技能集的嵌入映射到 contentVector。 由于这些文档携带矢量,因此全文查询和矢量查询都可以返回它们。
配置 CSV 管道:
创建 CSV 技能集:
POST <search-endpoint>/skillsets?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "csv-embedding-skillset", "description": "Vectorize CSV ticket content for the shared index.", "skills": [ { "@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill", "name": "csv-embedding", "context": "/document", "resourceUri": "<resource-endpoint>", "deploymentId": "<embedding-deployment-name>", "modelName": "text-embedding-3-small", "dimensions": 1536, "inputs": [ { "name": "text", "source": "/document/content" } ], "outputs": [ { "name": "embedding", "targetName": "csv_content_vector" } ] } ] }响应返回 HTTP
201 Created。验证是否已创建技能集:
GET <search-endpoint>/skillsets/csv-embedding-skillset?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>响应包含
"name": "csv-embedding-skillset"以及skills数组中的一个技能。创建 CSV 索引器:
POST <search-endpoint>/indexers?api-version=2026-08-01-preview Content-Type: application/json Authorization: Bearer <search-access-token> { "name": "csv-indexer", "dataSourceName": "csv-blob-datasource", "targetIndexName": "multi-source-index", "skillsetName": "csv-embedding-skillset", "parameters": { "configuration": { "parsingMode": "delimitedText", "firstLineContainsHeaders": true, "delimitedTextDelimiter": ",", "indexedFileNameExtensions": ".csv" } }, "fieldMappings": [ { "sourceFieldName": "id", "targetFieldName": "id" }, { "sourceFieldName": "sourceType", "targetFieldName": "sourceType" }, { "sourceFieldName": "content", "targetFieldName": "content" }, { "sourceFieldName": "sourceUri", "targetFieldName": "sourceUri" }, { "sourceFieldName": "title", "targetFieldName": "title" }, { "sourceFieldName": "lastModified", "targetFieldName": "lastModified" }, { "sourceFieldName": "status", "targetFieldName": "status" }, { "sourceFieldName": "priority", "targetFieldName": "priority" } ], "outputFieldMappings": [ { "sourceFieldName": "/document/csv_content_vector", "targetFieldName": "contentVector" } ] }参考:创建索引器(REST API)、 索引 CSV blob 和文件,以及 输出字段映射
响应返回 HTTP
201 Created。 索引器会自动启动其第一次运行。验证索引器是否处理了这两行:
GET <search-endpoint>/indexers/csv-indexer/status?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>等待
lastResult.status显示success,并确认lastResult.itemsFailed为0。 如果状态显示inProgress,请等待 15 秒,然后再次检查。 您将在本教程的后续部分通过查询索引来验证这两行 CSV 数据。
运行和监视索引器
创建索引器时,每个索引器都会自动启动其首次运行。 若要启动另一个运行并验证结果::
运行三个索引器:
POST <search-endpoint>/indexers/docx-indexer/run?api-version=2026-08-01-preview Content-Type: application/json Content-Length: 0 Authorization: Bearer <search-access-token>POST <search-endpoint>/indexers/json-indexer/run?api-version=2026-08-01-preview Content-Type: application/json Content-Length: 0 Authorization: Bearer <search-access-token>POST <search-endpoint>/indexers/csv-indexer/run?api-version=2026-08-01-preview Content-Type: application/json Content-Length: 0 Authorization: Bearer <search-access-token>Reference:Run Indexer (REST API)
每个运行请求返回包含空正文的 HTTP
202 Accepted。 某些 REST 客户端对于不含正文的请求需要Content-Length: 0标头。注释
如果源数据自上次运行以来未更改,索引器可能会报告
itemsProcessed为0。 这种行为是预期现象,因为索引器使用变更检测,并跳过未修改的 Blob。检查每个索引器的状态:
GET <search-endpoint>/indexers/docx-indexer/status?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>GET <search-endpoint>/indexers/json-indexer/status?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>GET <search-endpoint>/indexers/csv-indexer/status?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>对于每个索引器,请确认
lastResult.status为success,且lastResult.itemsFailed为0。 服务会在lastResult中报告处理详情;请在下一部分验证索引文档计数,因为投影得到的分块和解析后的记录不一定与源 Blob 一一对应。
查询共享索引
使用以下请求验证合并的结果。
验证联合结果
返回由三个索引器编写的所有文档:
POST <search-endpoint>/indexes/multi-source-index/docs/search?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer <search-access-token>
{
"search": "*",
"select": "id,parentId,sourceType,title",
"count": true
}
结果包含两个 JSON 产品、两个 CSV 票证和一个或多个 DOCX 区块。 如果示例 DOCX 生成一个区块, @odata.count 则为 5. 确认所有三个 sourceType 值均出现:docx、json 和 csv。
按鉴别器查询
返回两个 JSON 产品:
POST <search-endpoint>/indexes/multi-source-index/docs/search?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer <search-access-token>
{
"search": "*",
"filter": "sourceType eq 'json'",
"select": "id,sourceType,title,category,price",
"count": true
}
确认 @odata.count 为 2。 结果都具有 category 值和 price 值。
status和priority字段不在选择列表中,因为它们属于 CSV 架构。
运行全文查询
全文搜索会考虑所有具有匹配可搜索文本的文档,包括具有 null 向量的 JSON 记录。
POST <search-endpoint>/indexes/multi-source-index/docs/search?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer <search-access-token>
{
"search": "search product",
"searchFields": "content,title",
"select": "id,parentId,sourceType,title,content",
"count": true
}
结果包括来自任何源类型的文档,这些文档的 content 或 title 字段中包含“search”或“product”。 使用示例数据时,应会匹配到 DOCX 分块(包含“search”)和 CSV 工单(包含“product”)中的内容。
运行矢量查询
将文本发送到索引向量器,而不是粘贴 1,536 向量值。 结果包含矢量化 DOCX 和 CSV 文档,而不是 NULL 的 contentVector JSON 文档。
POST <search-endpoint>/indexes/multi-source-index/docs/search?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer <search-access-token>
{
"vectorQueries": [
{
"kind": "text",
"text": "search indexing issue",
"fields": "contentVector",
"k": 3
}
],
"select": "id,parentId,sourceType,title,content"
}
确认没有结果包含 "sourceType": "json"。 JSON 文档被排除,因为它们 contentVector 为 null。
运行筛选的矢量查询
将矢量结果限制为 CSV 票证:
POST <search-endpoint>/indexes/multi-source-index/docs/search?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer <search-access-token>
{
"filter": "sourceType eq 'csv'",
"vectorFilterMode": "preFilter",
"vectorQueries": [
{
"kind": "text",
"text": "deployment review",
"fields": "contentVector",
"k": 2
}
],
"select": "id,sourceType,title,status,priority"
}
确认所有结果都具有 "sourceType": "csv" 并包含 status 和 priority 字段。
运行混合查询
在一个请求中合并关键字和矢量检索:
POST <search-endpoint>/indexes/multi-source-index/docs/search?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer <search-access-token>
{
"search": "search issue",
"searchFields": "content,title",
"vectorQueries": [
{
"kind": "text",
"text": "search issue",
"fields": "contentVector",
"k": 3
}
],
"select": "id,parentId,sourceType,title,content"
}
混合查询将关键字匹配(可以包含 JSON 文档)与矢量匹配(不包括 null 向量文档)组合在一起。 当关键字和矢量词在管道之间匹配时,合并的结果集可以包含来自所有三种源类型的文档。
有关更多查询选项,请参阅 “创建矢量查询 ”和 “创建混合查询”。
管理和核对索引内容
将每个索引器视为独立编写器,并为其文档键值定义所有权和清理规则。
单独监视、计划、运行和重置每个索引器。 某个管道发生故障,并不会删除另一个管道已经写入的文档。 例如,格式不正确的 CSV 可能会导致
csv-indexer失败,而不会使现有文档或其他索引器不可用。 有关计划选项和详细状态字段,请参阅 “计划索引器 ”和 “监视索引器”状态。保持直接 JSON 和 CSV 密钥稳定且全局唯一。 不要在管道之间重复使用密钥。
预计 DOCX 投影将重新运行,以通过子文档与父文档之间的关系,使过期的子文档保持一致。 生成的子键可能会发生变化,因此应通过
parentId来识别投影组,而不是预测子键。 有关投影生命周期的详细信息,请参阅 内容生命周期。在依赖已删除的 DOCX 父 blob 来删除其投影子项之前,请先配置适当的 blob 删除检测策略。
Caution
直接的一对多解析需要由应用程序负责清理。 Blob 删除检测策略不适用于从 JSON 数组元素或 CSV 行创建的搜索文档。 删除某个元素或行,或者删除其源 Blob,可能会导致目标文档仍保留在索引中。 使用 Delete 文档 显式删除每个孤立项,或者从权威文档键集中重新生成索引。
Troubleshooting
下表列出了运行三个管道时的常见问题和解决方法。
| 症状 | 可能的原因 | 解决方案 |
|---|---|---|
lastResult.itemsFailed 大于零 |
源文档的格式异常,或者嵌入技能接收到空文本。 | 检查 lastResult.errors 索引器状态响应中是否存在特定错误消息和失败的文档密钥。 |
所有索引器均成功后,@odata.count 仍低于预期 |
索引器尚未完成其运行,DOCX 生成了不同的区块数,或键冲突重写了文档。 | 等待所有三个索引器报告 success。 确认显示所有三 sourceType 个值,并验证 JSON 和 CSV 密钥是否使用不同的前缀(json_, csv_)。 |
| 矢量查询返回零结果 | 索引中的向量器配置与索引时使用的嵌入模型不匹配,或者没有文档填充 contentVector 值。 |
确认向量化器的 deploymentId 和 modelName 与技能组中的值匹配。 确认 DOCX 和 CSV 索引器已完成,且无失败。 |
| JSON 文档显示在矢量查询结果中 | JSON 索引器意外填充了 contentVector。 |
确认 json-indexer 没有以 contentVector 为目标的 outputFieldMappings。 JSON 记录应将 contentVector 保留为 null。 |
| CSV 索引器失败并出现分析错误 | CSV 文件具有未转义的逗号、不匹配的引号或编码问题。 | 打开 CSV 文件并验证带逗号的字段是否括在双引号中。 使用 UTF-8 编码保存文件。 |
"The index 'multi-source-index' was not found" 查询期间出错 |
未创建索引,或者已将查询发送到错误的搜索服务。 | 确认 <search-endpoint> 是否指向正确的服务。 运行 GET <search-endpoint>/indexes?api-version=2026-08-01-preview 以列出索引。 |
运行索引器请求返回 HTTP 411 Length Required |
POST 请求没有正文,REST 客户端没有发送 Content-Length 标头。 |
将 Content-Length: 0 添加到请求标头中。 某些 REST 客户端需要显式将此标头用于具有空正文的 POST 请求。 |
重新运行显示 itemsProcessed 等于 0 |
自上次运行以来,源 Blob 未发生变化。 | 这是预期的行为。 索引器使用变更检测,并跳过未发生变化的 Blob 对象。 若要强制重新处理,请先通过发送 POST <search-endpoint>/indexers/<indexer-name>/reset?api-version=2026-08-01-preview 和 Content-Length: 0 持有者令牌标头来重置索引器。 |
清理资源
如果不再需要在本教程中创建的Azure AI 搜索对象,请按以下依赖项顺序将其删除:
删除索引器:
DELETE <search-endpoint>/indexers/docx-indexer?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>DELETE <search-endpoint>/indexers/json-indexer?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>DELETE <search-endpoint>/indexers/csv-indexer?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>每次删除操作都会在成功时返回 HTTP
204 No Content。 如果收到404 Not Found,则索引器已被删除。删除技能集:
DELETE <search-endpoint>/skillsets/docx-semantic-skillset?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>DELETE <search-endpoint>/skillsets/csv-embedding-skillset?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>每次删除操作都会在成功时返回 HTTP
204 No Content。删除数据源:
DELETE <search-endpoint>/datasources/docx-blob-datasource?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>DELETE <search-endpoint>/datasources/json-blob-datasource?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>DELETE <search-endpoint>/datasources/csv-blob-datasource?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>Reference:Delete Data Source (REST API)
每次删除操作都会在成功时返回 HTTP
204 No Content。删除索引:
DELETE <search-endpoint>/indexes/multi-source-index?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>Reference:Delete Index (REST API)
成功时返回 HTTP
204 No Content。验证是否已删除索引器:
GET <search-endpoint>/indexers?api-version=2026-08-01-preview Authorization: Bearer <search-access-token>Reference:List Indexers (REST API)
确认
docx-indexer,json-indexer并且csv-indexer不再出现在响应中。如果为此练习创建了资源组,请删除它及其包含的所有资源:
az group delete --name <resource-group-name> --yes --no-wait该命令会立即返回并异步删除资源组及其所有资源。