从 Azure Blob 存储索引数据

本文将介绍如何配置索引器,该索引器从 Azure Blob 存储导入内容,并使内容在 Azure AI 搜索中可供搜索。 索引器的输入是单个容器中的 Blob。 输出是一个搜索索引,其中包含可搜索的内容和存储在各个字段中的元数据。

本文对创建索引器进行了补充,其中包含特定于 Blob 存储的信息。 它使用 REST API 演示所有索引器通用的工作流,该工作流包含三个部分:创建数据源、创建索引、创建索引器。 提交“创建索引器”请求时,将提取数据。

Blob 索引器经常用于 AI 扩充和基于文本的处理。 本文重点介绍基于文本的索引的索引器,其中仅引入了全文搜索场景的文本内容和元数据。

先决条件

  • Azure Blob 存储,标准性能(常规用途 v2)。

  • Blob 存储访问层包括热访问层、冷访问层和存档访问层。 搜索索引器只能访问热访问层和冷访问层。

  • 提供文本内容和元数据的 blob。 如果 blob 包含二进制内容或非结构化文本,请考虑为映像和自然语言处理添加 AI 扩充。 Blob 内容不得超出搜索服务层级的索引器限制

  • 支持的网络配置和数据访问。 至少需要在 Azure 存储中拥有读取权限。 包含访问密钥的存储连接字符串提供对存储内容的读取访问。 如果使用 Microsoft Entra 登录名和角色,请确保搜索服务的托管标识具有“存储 Blob 数据读取者”权限。

    默认情况下,搜索和存储都接受来自公共 IP 地址的请求。 如果网络安全不是当务之急,只需使用连接字符串和读取权限即可为 Blob 数据编制索引。 准备好添加网络保护后,请查看索引器访问受 Azure 网络安全功能保护的内容,获取有关数据访问的指导。

  • 若要构建与本文所示调用类似的 REST 调用,请使用 REST 客户端

支持的文档格式

Blob 索引器可从以下文档格式提取文本:

确定要为哪些 blob 编制索引

确定要索引哪些 blob在建立索引之前,请查看源数据,以确定是否应提前进行任何更改。 索引器一次可以为一个容器中的内容编制索引。 默认情况下,将处理容器中的所有 blob。 有多个选项来进行更有选择性的处理:

  • 将 blob 放置在虚拟文件夹中。 索引器数据源定义包括可以采用虚拟文件夹的“查询”参数。 如果指定一个虚拟文件夹,则只会为该文件夹中的 blob 编制索引。

  • 按文件类型包含或排除 blob。 支持的文档格式列表可帮助你确定要排除的 blob。 例如,你可能希望排除不提供可搜索文本的图像或音频文件。 此功能通过索引器中的配置设置进行控制。

  • 包含或排除任意 blob。 如果出于某种原因想要跳过特定的 blob,可在 Blob 存储中向 blob 添加以下元数据属性和值。 当索引器遇到此属性时,它会在索引编制运行中跳过相应 blob 或其内容。

    属性名称 属性值 说明
    “AzureSearch_Skip” "true" 指示 Blob 索引器完全跳过该 Blob, 既不尝试提取元数据,也不提取内容。 如果特定的 Blob 反复失败并且中断编制索引过程,此属性非常有用。
    “AzureSearch_SkipContent” "true" 跳过内容并仅提取元数据。 此属性等效于"dataToExtract" : "allMetadata"中所述的 "dataToExtract" : "allMetadata" 设置,仅作用于特定的 blob。

如果未设置包含或排除的条件,索引器会将不符合条件的 Blob 报告为错误,并继续。 如果出现足够多的错误,处理可能会停止。 可在索引器配置设置中指定错误容错。

索引器通常会为每个 blob 创建一个搜索文档,其中的文本内容和元数据作为索引中的可搜索字段来捕获。 如果 blob 是整个文件,则可以将其解析为多个搜索文档。 例如,可以解析 CSV 文件中的行,以便为每行创建一个搜索文档。

复合或嵌入式文档(例如 ZIP 存档、嵌入了带附件 Outlook 电子邮件的 Word 文档或带附件的 .MSG 文件)也以单一文档的形式编制索引。 例如,从 .MSG 文件的附件中提取的所有图像将在 normalized_images 字段中返回。 如果有图像,请考虑添加 AI 扩充,以从该内容中获取更多搜索实用工具。

文档的文本内容将提取到名为 "content" 的字符串字段中。 还可以提取标准和用户定义的元数据。

为 Blob 元数据编制索引

还可以为 Blob 元数据编制索引,如果你认为任何标准或自定义元数据属性在筛选器和查询中有用,则其会很实用。

可以逐字提取任何由用户指定的元数据属性。 若要接收这些值,必须在 Edm.String 类型的搜索索引中定义字段,其名称与 blob 的元数据密钥名称相同。 例如,如果 blob 有值为 High 的元数据密钥 Sensitivity,则应在搜索索引中定义一个名为 Sensitivity 的字段,该字段将用值 High 填充。

可以将标准 blob 元数据属性提取到下列名称和类型类似的字段中。 Blob 索引器自动为这些 blob 元数据属性创建内部字段映射,将原始的连字符名称 ("metadata-storage-name") 转换为带下划线的等效名称 ("metadata_storage_name")。

你仍需要将带下划线的字段添加到索引定义中,但可以省略字段映射,因为索引器会自动进行关联。

  • metadata_storage_name () - blob 的文件名称。 例如,对于 Blob /my-container/my-folder/subfolder/resume.pdf 而言,此字段的值是 resume.pdf

  • metadata_storage_path () - blob 的完整 URI,其中包括存储帐户。 例如: https://myaccount.blob.core.chinacloudapi.cn/my-container/my-folder/subfolder/resume.pdf

  • metadata_storage_content_type - 用于上传 Blob 的代码指定的内容类型。 例如,application/octet-stream

  • metadata_storage_last_modified () - blob 的上次修改的时间戳。 Azure AI 搜索使用此时间戳来识别已更改的 blob,避免在初次编制索引之后再次为所有内容编制索引。

  • metadata_storage_size () - blob 大小,以字节为单位。

  • metadata_storage_content_md5 () - blob 内容的 MD5 哈希(如果有)。

  • metadata_storage_sas_token () - 一个临时 SAS 令牌,可由自定义技能用来获取对 Blob 的访问权限。 此令牌可能会过期,因此不应存储起来供后续使用。

最后,正在为其编制索引的 blob 文档格式的所有特定元数据属性也都可以在索引架构中存在表示形式。 有关特定于内容的元数据的详细信息,请参阅内容元数据属性

务必注意,无需在搜索索引中为上述所有属性定义字段 - 只需捕获应用程序所需的属性。

目前,此索引器不支持为 blob 索引标记编制索引。

定义数据源

数据源定义指定要编制索引的数据、凭据和用于标识数据更改的策略。 数据源定义为独立的资源,以便它可以被多个索引器使用。

  1. 创建或更新数据源以设置其定义:

    {
        "name" : "my-blob-datasource",
        "type" : "azureblob",
        "credentials" : { "connectionString" : "DefaultEndpointsProtocol=https;AccountName=<account name>;AccountKey=<account key>;" },
        "container" : { "name" : "my-container", "query" : "<optional-virtual-directory-name>" }
    }
    
  2. 将 "type" 设置为 "azureblob"(必需)。

  3. 将 "credentials" 设置为一个 Azure 存储连接字符串。 下一部分介绍支持的格式。

  4. 将 "container" 设置为 Blob 容器,并使用 "query" 指定任何子文件夹。

如果希望索引器在源文档被标记为待删除时删除搜索文档,则数据源定义还可以包含软删除策略

受支持的凭据和连接字符串

索引器可以使用以下连接连接到 Blob 容器。

完全访问存储帐户连接字符串
{ "connectionString" : "DefaultEndpointsProtocol=https;AccountName=<your storage account>;AccountKey=<your account key>;" }
可以通过在左侧导航窗格中选择“访问密钥”,从 Azure 门户的“存储帐户”页中获取连接字符串。 请确保选择完整的连接字符串,而不只是一个密钥。
托管标识连接字符串
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.Storage/storageAccounts/<your storage account name>/;" }
此连接字符串不需要帐户密钥,但先前必须已将搜索服务配置为使用托管标识进行连接
存储帐户共享访问签名** (SAS) 连接字符串
{ "connectionString" : "BlobEndpoint=https://<your account>.blob.core.chinacloudapi.cn/;SharedAccessSignature=?sv=2016-05-31&sig=<the signature>&spr=https&se=<the validity end time>&srt=co&ss=b&sp=rl;" }
SAS 应具有容器和对象(本例中为 blob)的列表和读取权限。
容器共享访问签名
{ "connectionString" : "ContainerSharedAccessUri=https://<your storage account>.blob.core.chinacloudapi.cn/<container name>?sv=2016-05-31&sr=c&sig=<the signature>&se=<the validity end time>&sp=rl;" }
SAS 应具有容器的列表和读取权限。 有关详细信息,请参阅使用共享访问签名

注意

如果使用 SAS 凭据,则需使用续订的签名定期更新数据源凭据,以防止其过期。 如果 SAS 凭据过期,索引器会失败并出现类似于“连接字符串中提供的凭据无效或已过期”的错误消息。

将搜索字段添加到索引

搜索索引中,添加字段以接受 Azure Blob 的内容和元数据。

  1. 创建或更新索引以定义将存储 Blob 内容和元数据的搜索字段:

    POST https://[service name].search.azure.cn/indexes?api-version=2020-06-30
    {
        "name" : "my-search-index",
        "fields": [
            { "name": "ID", "type": "Edm.String", "key": true, "searchable": false },
            { "name": "content", "type": "Edm.String", "searchable": true, "filterable": false },
            { "name": "metadata_storage_name", "type": "Edm.String", "searchable": false, "filterable": true, "sortable": true  },
            { "name": "metadata_storage_size", "type": "Edm.Int64", "searchable": false, "filterable": true, "sortable": true  },
            { "name": "metadata_storage_content_type", "type": "Edm.String", "searchable": false, "filterable": true, "sortable": true },        
        ]
    }
    
  2. 创建文档键字段 ("key": true)。 对于 Blob 内容,最佳候选项是元数据属性。

    • metadata_storage_path(默认)对象或文件的完整路径。 键字段(本例中的“ID”)将使用 metadata_storage_path 中的值填充,因为这是默认值。

    • metadata_storage_name 仅在名称唯一时可用。 如果希望此字段作为键,请将 "key": true 移动到此字段定义。

    • 要添加到 Blob 中的自定义元数据属性。 这种做法需要 Blob 上传过程将该元数据属性添加到所有 Blob。 由于键是必需的属性,因此无法对任何缺少值的 blob 编制索引。 如果使用自定义元数据属性作为键,请避免更改该属性。 如果键属性发生更改,索引器将为同一 Blob 添加重复的文档。

    元数据属性通常包括对文档键无效的字符,例如 /-。 因为索引器具有“base64EncodeKeys”属性(默认为 true),所以它会自动对元数据属性进行编码,无需进行配置或字段映射。

  3. 添加 "content"字段,以通过 Blob 的 "content" 属性存储从每个文件中提取的文本。 不需要使用此名称,但这样做则可以利用隐式字段映射。

  4. 为标准元数据属性添加字段。 索引器可以读取自定义元数据属性、标准元数据属性和内容特定的元数据属性。

配置和运行 blob 索引器

创建索引和数据源后,便可以准备创建索引器。 索引器配置指定控制运行时行为的输入、参数和属性。 还可指定要为 blob 的哪些部分编制索引。

  1. 通过为索引器命名并引用数据源和目标索引来创建或更新索引器

    POST https://[service name].search.azure.cn/indexers?api-version=2020-06-30
    {
      "name" : "my-blob-indexer",
      "dataSourceName" : "my-blob-datasource",
      "targetIndexName" : "my-search-index",
      "parameters": {
          "batchSize": null,
          "maxFailedItems": null,
          "maxFailedItemsPerBatch": null,
          "base64EncodeKeys": null,
          "configuration": {
              "indexedFileNameExtensions" : ".pdf,.docx",
              "excludedFileNameExtensions" : ".png,.jpeg",
              "dataToExtract": "contentAndMetadata",
              "parsingMode": "default"
          }
      },
      "schedule" : { },
      "fieldMappings" : [ ]
    }
    
  2. 如果默认(10 个文档)未充分利用可用资源或可用资源不足,则设置 batchSize。 默认批大小特定于数据源。 当平均文档大小较大时,Blob 索引编制会将批大小设置为 10 个文档。

  3. 在“配置”下,根据文件类型控制要为哪些 blob 编制索引,或者保留为不指定以检索所有 blob。

    对于 "indexedFileNameExtensions",请提供文件扩展名的逗号分隔列表(带前导点)。 为 "excludedFileNameExtensions" 执行相同的操作来指定应跳过哪些扩展名。 如果这两个列表中存在同一个扩展名,将从索引编制中排除该扩展名。

  4. 在“配置”下,设置“dataToExtract”以控制对 Blob 的哪些部分编制索引:

  5. 在“configuration”下,设置“parsingMode”。 默认分析模式是每个 Blob 的一个搜索文档。 如果 Blob 是纯文本,则可以通过切换到纯文本解析来获得更好的性能。 如果您需要更高细粒度的解析,也就是将 Blob 映射到多个搜索文档,请指定不同的模式。 Blob 支持一对多分析,其中包括:

  6. 如果字段名称或类型存在差异,或者需要在搜索索引中使用多个版本的源字段,请指定字段映射

    在 Blob 索引编制中,通常可以省略字段映射,因为索引器内置支持将 "content" 和元数据属性映射到索引中命名和类型类似的字段。 对于元数据属性,索引器自动将搜索索引中的连字符 - 替换为下划线。

  7. 有关其他属性的详细信息,请参阅创建索引器。 有关参数说明的完整列表,请参阅 REST API 中的 Blob 配置参数

创建索引器后,它会自动运行。 可以将“已禁用”设置为 true 以防止这种情况。 若要控制索引器执行,请按需运行索引器按计划运行索引器

检查索引器状态

若要监视索引器状态和执行历史记录,请发送获取索引器状态请求:

GET https://myservice.search.azure.cn/indexers/myindexer/status?api-version=2020-06-30
  Content-Type: application/json  
  api-key: [admin key]

响应包括状态和已处理的项数。 它应如以下示例所示:

    {
        "status":"running",
        "lastResult": {
            "status":"success",
            "errorMessage":null,
            "startTime":"2022-02-21T00:23:24.957Z",
            "endTime":"2022-02-21T00:36:47.752Z",
            "errors":[],
            "itemsProcessed":1599501,
            "itemsFailed":0,
            "initialTrackingState":null,
            "finalTrackingState":null
        },
        "executionHistory":
        [
            {
                "status":"success",
                "errorMessage":null,
                "startTime":"2022-02-21T00:23:24.957Z",
                "endTime":"2022-02-21T00:36:47.752Z",
                "errors":[],
                "itemsProcessed":1599501,
                "itemsFailed":0,
                "initialTrackingState":null,
                "finalTrackingState":null
            },
            ... earlier history items
        ]
    }

执行历史记录包含最多 50 个最近完成的执行,它们按时间倒序排列,这样最新的执行最先显示。

处理错误

在索引过程中经常发生的错误包括:内容类型不受支持、内容缺失或 blob 过大。

默认情况下,Blob 索引器一旦遇到包含不受支持内容类型(例如音频文件)的 Blob 时,就会立即停止。 可以使用“excludedFileNameExtensions”参数跳过某些内容类型。 但是,你可能希望即使出现错误也继续进行索引,之后再调试各个文档。 若要详细了解索引器错误,请参阅索引器故障排除指南索引器错误和警告

可以通过五个索引器属性控制索引器在出现错误时的响应。

PUT /indexers/[indexer name]?api-version=2020-06-30
{
  "parameters" : { 
    "maxFailedItems" : 10, 
    "maxFailedItemsPerBatch" : 10,
    "configuration" : { 
        "failOnUnsupportedContentType" : false, 
        "failOnUnprocessableDocument" : false,
        "indexStorageMetadataOnlyForOversizedDocuments": false
      }
    }
}
参数 有效值 说明
"maxFailedItems" -1、null 或 0、正整数 如果在任意处理点(无论是在解析 blob 时,还是在将文档添加到索引时)发生错误,继续进行索引。 将这些属性设置为可接受的失败数。 如果值为 -1,则不管发生多少错误,都可以进行处理。 否则,该值为正整数。
"maxFailedItemsPerBatch" -1、null 或 0、正整数 与上面相同,但用于批处理索引编制。
"failOnUnsupportedContentType" true 或 false 如果索引器无法确定内容类型,请指定是继续作业还是使作业失败。
"failOnUnprocessableDocument" true 或 false 如果索引器无法处理其他受支持的内容类型的文档,请指定是继续作业还是使作业失败。
"indexStorageMetadataOnlyForOversizedDocuments" true 或 false 过大的 blob 会被默认视为错误。 如果将此参数设置为 true,则即使无法为内容编制索引,索引器也会尝试为其元数据编制索引。 有关 blob 大小的限制,请参阅服务限制

另请参阅