默认情况下,索引器将 Blob 或文件的内容视为单个搜索文档。 如果要在搜索索引中提供更精细的表示形式,可以设置 parsingMode 值,以便从一个 Blob 或文件创建多个搜索文档。 与 parsingMode 值相关导致许多搜索文档的格式包括 delimitedText (适用于 CSV)以及 jsonArray 或 jsonLines (适用于 JSON)。
使用这些分析模式中的任何一种时,出现的新搜索文档必须具有唯一的文档键,并且确定该值的来源时会出现问题。 父 Blob 至少有一个形如 metadata_storage_path property 的唯一值,但如果它将该值贡献给多个搜索文档,则在索引中该键不再唯一。
为了解决此问题,Blob 索引器生成一个 AzureSearch_DocumentKey,用于唯一标识从单个 Blob 父级创建的每个子搜索文档。 本文介绍此功能的工作原理。
一对多文档密钥
文档键唯一标识索引中的每个文档。 如果未指定分析模式,并且搜索文档键的索引器定义中没有 显式字段映射 ,Blob 索引器会自动映射 metadata_storage_path property 为文档键。 此默认映射可确保每个 Blob 显示为不同的搜索文档。 它还消除了您手动创建此字段映射的需要。 通常,具有相同名称和类型的字段是唯一自动映射的字段。
在一对多的搜索文档场景中,无法实现基于metadata_storage_path property 的隐式文档密钥。 解决方法是,Azure AI 搜索可以为从 Blob 中提取的每个实体生成文档密钥。 系统将生成一个调用 AzureSearch_DocumentKey 的键,并将其添加到每个搜索文档中。 索引器会跟踪从每个 Blob 创建的“许多文档”,并在源数据随时间变化时,能够针对搜索索引进行更新。
默认情况下,如果未指定用于键索引字段的显式字段映射,将使用 AzureSearch_DocumentKey 字段映射函数将 base64Encode 映射到该字段。
Example
假设索引定义包含以下字段:
idtemperaturepressuretimestamp
Blob 容器中包含以下结构的 Blob:
Blob1.json
{ "temperature": 100, "pressure": 100, "timestamp": "2024-02-13T00:00:00Z" }
{ "temperature" : 33, "pressure" : 30, "timestamp": "2024-02-14T00:00:00Z" }
Blob2.json
{ "temperature": 1, "pressure": 1, "timestamp": "2023-01-12T00:00:00Z" }
{ "temperature" : 120, "pressure" : 3, "timestamp": "2022-05-11T00:00:00Z" }
创建索引器并将 parsingMode 设置为 jsonLines - 不指定键字段的任何显式字段映射时,将隐式应用以下映射。
{
"sourceFieldName" : "AzureSearch_DocumentKey",
"targetFieldName": "id",
"mappingFunction": { "name" : "base64Encode" }
}
此设置会生成明确化的文档键,如下图所示(为简洁起见,缩短了 base64 编码的 ID)。
| ID | 温度 | 压力 | 时间戳 |
|---|---|---|---|
| aHR0...YjEuanNvbjsx | 100 | 100 | 2024-02-13T00:00:00Z |
| aHR0...YjEuanNvbjsy | 33 | 30 | 2024-02-14T00:00:00Z |
| aHR0...YjIuanNvbjsx | 1 | 1 | 2023-01-12T00:00:00Z |
| aHR0...YjIuanNvbjsy | 120 | 3 | 2022-05-11T00:00:00Z |
索引键字段的自定义字段映射
假设索引定义与前面的示例相同,并且你的 Blob 容器中包含具有以下结构的 blob:
Blob1.json
recordid, temperature, pressure, timestamp
1, 100, 100,"2024-02-13T00:00:00Z"
2, 33, 30,"2024-02-14T00:00:00Z"
Blob2.json
recordid, temperature, pressure, timestamp
1, 1, 1,"20123-01-12T00:00:00Z"
2, 120, 3,"2022-05-11T00:00:00Z"
使用 delimitedText 创建索引器时,将字段映射函数设置为键字段可能很自然,如下所示:
{
"sourceFieldName" : "recordid",
"targetFieldName": "id"
}
但是,此映射不会导致索引中显示四个文档,是因为字段recordid在各个 Blob 中并不唯一。 因此,我们建议您利用从 AzureSearch_DocumentKey 属性应用到键索引字段的隐式字段映射来处理“一对多”的解析模式。
如果确实要设置显式字段映射,请确保所有 Blob 中每个单个实体的 sourceField 都是不同的。
注释
不应依赖 AzureSearch_DocumentKey 确保每个提取实体唯一性的方法,因为这种方法可能会发生变化,无法保证应用程序的需求。
在数据中指定索引键字段
假设与上一个示例相同的索引定义,并将 parsingMode 设置为 jsonLines 不指定任何显式字段映射,因此映射如第一个示例中所示,假设 Blob 容器具有具有以下结构的 Blob:
Blob1.json
id, temperature, pressure, timestamp
1, 100, 100,"2024-02-13T00:00:00Z"
2, 33, 30,"2024-02-14T00:00:00Z"
Blob2.json
id, temperature, pressure, timestamp
1, 1, 1,"2023-01-12T00:00:00Z"
2, 120, 3,"2022-05-11T00:00:00Z"
每个文档都包含字段 id ,该字段定义为 key 索引中的字段。 在这种情况下,系统会生成一个唯一的AzureSearch_DocumentKeyfor the document, but it isn't used as the "key." Instead, the value of theidfield is mapped to thekey字段。
与前面的示例类似,此映射不会导致索引中显示的四个文档,因为 id 该字段 在 Blob 中并不唯一。 出现这种情况时,任何指定 id 的 JSON 条目会与现有文档合并,而不是上传新的。 然后,索引将反映指定的 id项的最新状态。
局限性
从文件中的某一行创建索引中的文档项时,如本文所述,从文件中删除该行不会自动从索引中删除相应的条目。 若要删除文档条目,必须使用 REST API 删除作手动将删除请求提交到索引。
后续步骤
如果不熟悉 Blob 索引的基本结构和工作流,应首先使用 Azure AI 搜索查看 Azure Blob 存储索引 。 有关分析不同 Blob 内容类型模式的详细信息,请参阅以下文章。