使用 Azure AI 搜索索引器进行字段映射和转换
本文介绍如何设置显式字段映射,以在受支持的数据源中的源字段和搜索索引中的目标字段之间建立数据路径。
何时设置字段映射
Azure AI 搜索索引器加载搜索索引时,它会使用源到目标字段映射来确定数据路径。 隐式字段映射在内部进行,并在源与目标之间的字段名称和数据类型兼容时发生。 如果输入和输出不一致,你可以定义显式字段映射来设置数据路径,如本文所述。
字段映射还可用于通过映射函数进行轻量级数据转换,例如编码或解码。 如果需要进行更多处理,请考虑使用 Azure 数据工厂来弥补差距。
字段映射适用于:
数据路径两侧的物理数据结构。 技能创建的逻辑数据结构仅驻留在内存中。 请使用 outputFieldMappings 将内存中节点映射到搜索索引中的输出字段。
仅限父级 AI 搜索索引。 对于带有“子”文档或“块”的“二级”索引,请参阅高级字段映射方案。
仅限顶级搜索字段,其中
targetFieldName
是简单字段或集合。 目标字段不能是复杂类型。
支持的方案
请确保使用支持的数据源进行索引器驱动索引。
用例 | 说明 |
---|---|
名称差异 | 假设数据源包含名为 _city 的字段。 鉴于 Azure AI 搜索不允许以下划线开头的字段名称,你可以使用字段映射将“_city”有效地映射到“city”。 如果索引要求中包括从多个数据源检索内容(字段名称因源而异),则可以使用字段映射来明确路径。 |
类型差异 | 假设你想要一个类型为 Edm.String 的源整数字段,以便可以在搜索索引中搜索它。 由于类型不同,因此需要定义字段映射,以便数据路径成功。 请注意,与许多数据源相比,Azure AI 搜索具有的支持的数据类型更少。 如果要导入 SQL 数据,可使用字段映射来映射搜索索引中所需的 SQL 数据类型。 |
一对多数据路径 | 可以使用同一源字段中的内容填充索引中的多个字段。 例如,你可能想要将不同的分析器应用于每个字段,以支持客户端应用中的不同用例。 |
编码和解码 | 可以在索引编制过程中应用映射函数,以支持对数据进行 Base64 编码或解码。 |
拆分字符串或将数组重新强制转换为集合 | 可以应用映射函数来拆分包含分隔符的字符串,或将 JSON 数组发送到类型为 Collection(Edm.String) 的搜索字段。 |
注意
如果不存在字段映射,则索引器假设应将数据源字段映射到同名的索引字段。 添加字段映射会替代源和目标字段的默认字段映射。 有些索引器(如 Blob 存储索引器)自动为索引键字段添加默认字段映射。
字段映射不支持复杂字段。 源结构(嵌套或分层结构)必须与索引中的复杂类型完全匹配,这样默认映射才会生效。 有关详细信息,请参阅教程:为嵌套 JSON Blob 编制索引,其中包含示例。 如果收到类似于 "Field mapping specifies target field 'Address/city' that doesn't exist in the index"
的错误,这是因为目标字段映射不能是复杂类型。
可能只需复杂结构中的几个节点(视需要而定)。 若要获取单个节点,可以将传入数据平展成一个字符串集合(请参阅 outputFieldMappings 以了解此解决方法)。
定义字段映射
本部分介绍设置字段映射的步骤。
在 Azure SDK 中使用创建索引器、创建或更新索引器或等效方法。 下面是索引器定义的示例。
{ "name": "myindexer", "description": null, "dataSourceName": "mydatasource", "targetIndexName": "myindex", "schedule": { }, "parameters": { }, "fieldMappings": [], "disabled": false, "encryptionKey": { } }
填写
fieldMappings
数组以指定映射。 字段映射由 3 部分组成。"fieldMappings": [ { "sourceFieldName": "_city", "targetFieldName": "city", "mappingFunction": null } ]
属性 说明 sourceFieldName 必需。 表示数据源中的字段。 targetFieldName 可选。 表示搜索索引中的字段。 如果省略,则假定目标值为 sourceFieldName
。 目标字段必须是顶级简单字段或集合。 它不能是复杂类型或集合。 如果要处理数据类型问题,则在索引定义中指定字段的数据类型。 字段映射只需要有字段的名称。mappingFunction 可选。 由用于转换数据的预定义函数组成。
示例:名称或类型差异
显式字段映射为名称和类型不一致的情况建立数据路径。
Azure AI 搜索使用不区分大小写的比较,来解析字段映射中的字段和函数名称。 此操作很方便(大小写无需全都正确),但这表示数据源或索引无法具有仅大小写不同的字段。
PUT https://[service name].search.azure.cn/indexers/myindexer?api-version=[api-version]
Content-Type: application/json
api-key: [admin key]
{
"dataSourceName" : "mydatasource",
"targetIndexName" : "myindex",
"fieldMappings" : [ { "sourceFieldName" : "_city", "targetFieldName" : "city" } ]
}
示例:一对多或分叉数据路径
此示例将单个源字段映射到多个目标字段(“一对多”映射)。 可以将字段“分支”,将相同的源字段内容复制到两个不同的索引字段,这些字段将在索引中以不同方式进行分析或特性化。
"fieldMappings" : [
{ "sourceFieldName" : "text", "targetFieldName" : "textStandardEnglishAnalyzer" },
{ "sourceFieldName" : "text", "targetFieldName" : "textSoundexAnalyzer" }
]
可以对技能生成的内容使用类似的方法。
映射函数和示例
字段映射函数在将字段存储到索引中之前转换该字段的内容。 目前支持以下映射函数:
请注意,目前这些功能仅支持父索引。 它们与分块索引映射不兼容,因此,这些功能不能用于索引投影。
base64Encode 函数
执行输入字符串的 URL 安全 Base64 编码。 假定输入采用 UTF-8 进行编码。
示例:对文档键进行基本编码
Azure AI 搜索文档键中只能出现 URL 安全字符(以便可以使用查找 API 找到该文档)。 如果键的源字段包含 URL 不安全字符(例如 -
和 \
),在编制索引时,你可以使用 base64Encode
函数来转换该字段。
以下示例指定 metadata_storage_name
中的 base64Encode 函数以处理不受支持的字符。
PUT /indexers?api-version=2024-07-01
{
"dataSourceName" : "my-blob-datasource ",
"targetIndexName" : "my-search-index",
"fieldMappings" : [
{
"sourceFieldName" : "metadata_storage_name",
"targetFieldName" : "key",
"mappingFunction" : {
"name" : "base64Encode",
"parameters" : { "useHttpServerUtilityUrlTokenEncode" : false }
}
}
]
}
文档键(转换前后)的长度不能超过 1,024 个字符。 在搜索时检索编码的键时,请使用 base64Decode
函数获取原始键值,并使用它来检索源文档。
示例:使采用基本编码的字段“可搜索”
有时,需要使用一个字段的编码版本(如 metadata_storage_path
)作为键,但也需要未编码版本以进行全文搜索。 若要支持这两个场景,可以将 metadata_storage_path
映射到两个字段;一个用于键(编码版本),另一个用于在索引架构中可视为 searchable
的路径字段。
PUT /indexers/blob-indexer?api-version=2024-07-01
{
"dataSourceName" : " blob-datasource ",
"targetIndexName" : "my-target-index",
"schedule" : { "interval" : "PT2H" },
"fieldMappings" : [
{ "sourceFieldName" : "metadata_storage_path", "targetFieldName" : "key", "mappingFunction" : { "name" : "base64Encode" } },
{ "sourceFieldName" : "metadata_storage_path", "targetFieldName" : "path" }
]
}
示例 - 保留原始值
如果未指定字段映射,blob 存储索引器会自动将字段映射从 metadata_storage_path
(blob 的 URI)添加到索引键字段。 此值是 Base64 编码的,因此可以安全地作为 Azure AI 搜索文档键使用。 下面的示例演示如何同时将 metadata_storage_path
的 URL 安全 Base64 编码版本映射到 index_key
字段和将原始值保留在 metadata_storage_path
字段中:
"fieldMappings": [
{
"sourceFieldName": "metadata_storage_path",
"targetFieldName": "metadata_storage_path"
},
{
"sourceFieldName": "metadata_storage_path",
"targetFieldName": "index_key",
"mappingFunction": {
"name": "base64Encode"
}
}
]
如果未包含映射函数的 parameters 属性,该属性的默认值为 {"useHttpServerUtilityUrlTokenEncode" : true}
。
Azure AI 搜索支持两种不同的 Base64 编码。 在编码和解码同一字段时,应使用相同的参数。 在决定要使用哪些参数时,请参阅 base64 编码选项了解详细信息。
base64Decode 函数
执行输入字符串的 Base64 解码。 假设输入是 URL 安全的 Base64 编码字符串。
示例 - 解码 Blob 元数据或 URL
源数据可能包含 Base64 编码的字符串(例如 Blob 元数据字符串或 Web URL),你希望这些字符串可作为纯文本进行搜索。 可以在填充搜索索引时,使用 base64Decode
函数将编码的数据转换回到常规字符串。
"fieldMappings" : [
{
"sourceFieldName" : "Base64EncodedMetadata",
"targetFieldName" : "SearchableMetadata",
"mappingFunction" : {
"name" : "base64Decode",
"parameters" : { "useHttpServerUtilityUrlTokenDecode" : false }
}
}
]
如果未包含 parameters 属性,该属性的默认值为 {"useHttpServerUtilityUrlTokenEncode" : true}
。
Azure AI 搜索支持两种不同的 Base64 编码。 在编码和解码同一字段时,应使用相同的参数。 在决定要使用哪些参数时,请参阅 base64 编码选项了解详细信息。
base64 编码选项
Azure AI 搜索支持 URL 安全的 base64 编码和正常的 base64 编码。 在索引编制期间经过 base64 编码的字符串在以后应使用相同的编码选项进行解码,否则结果将与原始字符串不匹配。
如果将用于编码或解码的 useHttpServerUtilityUrlTokenEncode
或 useHttpServerUtilityUrlTokenDecode
参数分别设置为 true
,则 base64Encode
的行为与 HttpServerUtility.UrlTokenEncode 类似,base64Decode
的行为与 HttpServerUtility.UrlTokenDecode 类似。
警告
如果使用 base64Encode
来生成密钥值,则必须将 useHttpServerUtilityUrlTokenEncode
设置为 true。 只能将 URL 安全的 base64 编码用于密钥值。 请参阅命名规则了解键值中字符的整套限制。
Azure AI 搜索中的 .NET 库采用完整的 .NET 框架来提供内置编码。 useHttpServerUtilityUrlTokenEncode
和 useHttpServerUtilityUrlTokenDecode
选项应用了此内置功能。 如果使用 .NET Core 或其他框架,建议将这些选项设置为 false
并直接调用框架的编码和解码函数。
下表比较了对字符串 00>00?00
进行不同的 base64 编码的结果。 若要确定 base64 函数所需的处理(如有),请对字符串 00>00?00
应用库编码函数,然后比较输出和预期的输出 MDA-MDA_MDA
。
编码 | Base64 编码输出 | 库编码后的额外处理 | 库解码前的额外处理 |
---|---|---|---|
带填充的 Base64 | MDA+MDA/MDA= |
使用 URL 安全字符并删除填充 | 使用标准 base64 字符并添加填充 |
不带填充的 Base64 | MDA+MDA/MDA |
使用 URL 安全字符 | 使用标准 base64 字符 |
带填充的 URL 安全 Base64 | MDA-MDA_MDA= |
删除填充 | 添加填充 |
不带填充的 URL 安全 Base64 | MDA-MDA_MDA |
无 | 无 |
extractTokenAtPosition 函数
使用指定的分隔符拆分字符串字段,并在所生成拆分的指定位置处选取令牌。
此函数使用以下参数:
delimiter
:在拆分输入字符串时,用作分隔符的字符串。position
:在拆分输入字段串后要选取的位置,以零为底的整数。
例如,如果输入是 Jane Doe
,delimiter
是 " "
(空格)并且 position
是 0,则结果为 Jane
;如果 position
是 1,则结果是 Doe
。 如果位置引用的令牌不存在,则会返回错误。
示例 - 提取名称
数据源包含 PersonName
字段,并且想要为其编制索引作为两个单独的 FirstName
和 LastName
字段。 可以使用此函数来拆分将空格字符用作分隔符的输入。
"fieldMappings" : [
{
"sourceFieldName" : "PersonName",
"targetFieldName" : "FirstName",
"mappingFunction" : { "name" : "extractTokenAtPosition", "parameters" : { "delimiter" : " ", "position" : 0 } }
},
{
"sourceFieldName" : "PersonName",
"targetFieldName" : "LastName",
"mappingFunction" : { "name" : "extractTokenAtPosition", "parameters" : { "delimiter" : " ", "position" : 1 } }
}]
jsonArrayToStringCollection 函数
将已格式化为 JSON 字符串数组的字符串转换为可用于填充索引中 Collection(Edm.String)
字段的字符串数组。
例如,如果输入字符串是 ["red", "white", "blue"]
,类型 Collection(Edm.String)
的目标字段由 red
、white
和 blue
这三个值填充。 对于无法分析为 JSON 字符串数组的输入值,则会返回错误。
示例 - 使用关系数据填充集合
Azure SQL 数据库不具有能自然映射到 Azure AI 搜索中 Collection(Edm.String)
字段的内置数据类型。 若要填充字符串集合字段,可将源数据预处理成 JSON 字符串数组,然后使用 jsonArrayToStringCollection
映射函数。
"fieldMappings" : [
{
"sourceFieldName" : "tags",
"mappingFunction" : { "name" : "jsonArrayToStringCollection" }
}]
urlEncode 函数
此函数可用于对字符串进行编码,使其是“URL 安全的”。 与包含 URL 中不允许的字符的字符串结合使用时,此函数会将这些“不安全”字符转换为字符实体等效项。 此函数使用 UTF-8 编码格式。
示例 - 文档键查找
如果只转换 URL 不安全字符,而将其他字符保留原样,则可以使用 urlEncode
函数来代替 base64Encode
函数。
例如,如果输入字符串是 <hello>
- 则 (Edm.String)
类型的目标字段中将填充值 %3chello%3e
在搜索时检索编码的键时,可以使用 urlDecode
函数获取原始键值,然后使用该值来检索源文档。
"fieldMappings" : [
{
"sourceFieldName" : "SourceKey",
"targetFieldName" : "IndexKey",
"mappingFunction" : {
"name" : "urlEncode"
}
}
]
urlDecode 函数
此函数使用 UTF-8 编码格式将 URL 编码的字符串转换为解码的字符串。
示例 - 解码 Blob 元数据
如果 blob 元数据包含非 ASCII 字符,某些 Azure 存储客户端会自动对这些元数据进行 URL 编码。 但是,若要使此类元数据可搜索(作为纯文本),可以在填充搜索索引时,使用 urlDecode
函数将编码的数据转换回到常规字符串。
"fieldMappings" : [
{
"sourceFieldName" : "UrlEncodedMetadata",
"targetFieldName" : "SearchableMetadata",
"mappingFunction" : {
"name" : "urlDecode"
}
}
]
fixedLengthEncode 函数
此函数将任意长度的字符串转换为固定长度的字符串。
示例 - 映射过长的文档键
当出现与文档键长度超过 1024 个字符相关的错误时,可以应用此函数来减少文档键的长度。
"fieldMappings" : [
{
"sourceFieldName" : "metadata_storage_path",
"targetFieldName" : "your key field",
"mappingFunction" : {
"name" : "fixedLengthEncode"
}
}
]
toJson 函数
此函数将字符串转换为格式化的 JSON 对象。 这可用于数据源(如 Azure SQL)本身不支持复合或分层数据类型的场景,然后将其映射到复杂字段。
示例 - 将文本内容映射到复杂字段
假设有一个包含 JSON 字符串的 SQL 行,该行需要映射到索引中的(相应定义的)复杂字段,toJson
函数可用于实现此目的。 例如,如果需要用以下数据填充索引中的复杂字段:
{
"id": "5",
"info": {
"name": "Jane",
"surname": "Smith",
"skills": [
"SQL",
"C#",
"Azure"
],
"dob": "2005-11-04T12:00:00"
}
}
这可以通过在 SQL 行中的 JSON 字符串列上使用 toJson
映射函数来实现,如下所示:{"id": 5, "info": {"name": "Jane", "surname": "Smith", "skills": ["SQL", "C#", "Azure"]}, "dob": "2005-11-04T12:00:00"}
。
需要指定字段映射,如下所示。
"fieldMappings" : [
{
"sourceFieldName" : "content",
"targetFieldName" : "complexField",
"mappingFunction" : {
"name" : "toJson"
}
}
]
高级字段映射方案
在具有“一对多”文档关系(例如数据分块或拆分)的情况下,请遵循以下准则,将字段从父文档映射到“子”文档(块):
1.跳过父文档索引
若要跳过父文档的索引(通过在技能组的 indexProjections
中将 projectionMode
设置为 skipIndexingParentDocuments
),请使用索引投影将字段从父文档映射到“子”文档。
2.为父文档和“子”文档编制索引
如果要为父文档和“子”文档编制索引:
- 使用字段映射将字段映射到父文档。
- 使用索引投影将字段映射到“子”文档。
3.将函数转换的值映射到父文档和/或“子”文档
如果父文档中的字段需要转换(使用映射函数,如编码),并且需要映射到父文档和/或“子”文档: