为 Azure Cosmos DB for Apache Gremlin 中的数据编制索引,以便在 Azure AI 搜索中进行查询

重要

根据补充使用条款,Azure Cosmos DB for Apache Gremlin 索引器目前处于公共预览阶段。 目前没有 SDK 支持。

本文将介绍如何配置索引器,该索引器从 Azure Cosmos DB for Apache Gremlin 导入内容,并使内容在 Azure AI 搜索中可供搜索

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

由于术语可能会造成混淆,特此提示,Azure Cosmos DB 索引编制Azure AI 搜索索引编制属于不同的操作。 在 Azure AI 搜索中编制索引可在搜索服务中创建并加载搜索索引。

先决条件

  • 注册预览版以提供方案反馈。 在提交表单后,你可以自动访问该功能。

  • 一个 Azure Cosmos DB 帐户、数据库、容器和项。 对 Azure AI 搜索和 Azure Cosmos DB 使用同一个区域,以降低延迟并避免带宽费用。

  • 针对 Azure Cosmos DB 集合的自动索引策略,设置为“一致”。 这是默认配置。 建议不要使用惰性索引编制,这可能会导致丢失数据。

  • 读取权限。 “完全访问权限”连接字符串包含授予对内容的访问权限的密钥,但如果使用的是 Azure 角色,请确保搜索服务托管标识具有“Cosmos DB 帐户读者角色”权限。

  • 一个 REST 客户端,用于创建数据源、索引和索引器。

定义数据源

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

对于此调用,请指定一个 REST API 预览版以创建通过 Azure Cosmos DB for Apache Gremlin 进行连接的数据源。 你可以使用 2021-04-01-preview 或更高版本。 建议使用最新的预览版 API。

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

     POST https://[service name].search.azure.cn/datasources?api-version=2024-05-01-preview
     Content-Type: application/json
     api-key: [Search service admin key]
     {
       "name": "[my-cosmosdb-gremlin-ds]",
       "type": "cosmosdb",
       "credentials": {
         "connectionString": "AccountEndpoint=https://[cosmos-account-name].documents.azure.cn;AccountKey=[cosmos-account-key];Database=[cosmos-database-name];ApiKind=Gremlin;"
       },
       "container": {
         "name": "[cosmos-db-collection]",
         "query": "g.V()"
       },
       "dataChangeDetectionPolicy": {
         "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
         "highWaterMarkColumnName": "_ts"
       },
       "dataDeletionDetectionPolicy": null,
       "encryptionKey": null,
       "identity": null
     }
     }
    
  2. 将 "type" 设置为 "cosmosdb"(必需)。

  3. 将“凭据”设置为连接字符串。 下一部分介绍受支持的格式。

  4. 将“容器”设置为集合。 “name” 属性是必需的,它指定图形的 ID。

    “查询”属性是可选的。 默认情况下,Azure Cosmos DB for Apache Gremlin 的 Azure AI 搜索索引器会使图中的每个顶点都成为索引中的文档。 边缘将被忽略。 查询默认值为 g.V()。 或者可以将查询设置为边缘编制索引。 要为边缘编制索引,请将查询设置为 g.E()

  5. 如果数据经常变动,且你希望索引器在后续运行时只获取新项和已更新项可以设置 “dataChangeDetectionPolicy”。 默认情况下,使用 _ts 作为高水位标记列启用增量进度。

  6. 如果要在删除源项时从搜索索引中删除搜索文档,可以设置 “dataDeletionDetectionPolicy”

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

索引器可以使用以下连接连接到集合。 对于面向 Azure Cosmos DB for Apache Gremlin 的连接,请确保在连接字符串中包含“ApiKind”。

避免在终结点 URL 中包含端口号。 如果包含端口号,连接将失败。

完全访问权限连接字符串
{ "connectionString" : "AccountEndpoint=https://<Cosmos DB account name>.documents.azure.cn;AccountKey=<Cosmos DB auth key>;Database=<Cosmos DB database id>;ApiKind=MongoDb" }
可以通过在左侧导航窗格中选择“密钥”,从 Azure 门户的 Azure Cosmos DB 帐户页中获取连接字符串。 请确保选择完整的连接字符串,而不只是一个密钥。
托管标识连接字符串
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.DocumentDB/databaseAccounts/<your cosmos db account name>/;(ApiKind=[api-kind];)" }
此连接字符串不需要帐户密钥,但你之前必须已将搜索服务配置为使用托管标识进行连接,并已创建一个授予“Cosmos DB 帐户读者角色”权限的角色分配。 有关详细信息,请参阅使用托管标识设置与 Azure Cosmos DB 数据库的索引器连接

将搜索字段添加到索引

搜索索引中,添加字段以接受源 JSON 文档或自定义查询投影的输出。 确保搜索索引架构与图形兼容。 对于 Azure Cosmos DB 中的内容,搜索索引架构应对应于数据源中的 Azure Cosmos DB 项

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

     POST https://[service name].search.azure.cn/indexes?api-version=2024-05-01-preview
     Content-Type: application/json
     api-key: [Search service admin key]
     {
        "name": "mysearchindex",
        "fields": [
         {
             "name": "rid",
             "type": "Edm.String",
             "facetable": false,
             "filterable": false,
             "key": true,
             "retrievable": true,
             "searchable": true,
             "sortable": false,
             "analyzer": "standard.lucene",
             "indexAnalyzer": null,
             "searchAnalyzer": null,
             "synonymMaps": [],
             "fields": []
         },{
         }, {
             "name": "label",
             "type": "Edm.String",
             "searchable": true,
             "filterable": false,
             "retrievable": true,
             "sortable": false,
             "facetable": false,
             "key": false,
             "indexAnalyzer": null,
             "searchAnalyzer": null,
             "analyzer": "standard.lucene",
             "synonymMaps": []
        }]
      }
    
  2. 创建文档键字段 ("key": true)。 对于已分区集合,默认文档键是 Azure Cosmos DB _rid 属性,Azure AI 搜索会自动将其重命名为 rid,因为字段名称不能以下划线字符开头。 此外,Azure Cosmos DB 的 _rid 值包含了在 Azure AI 搜索键中无效的字符。 因此,_rid 值采用 Base64 编码。

  3. 创建其他字段,以获得更多可搜索的内容。 有关详细信息,请参阅创建索引

映射数据类型

JSON 数据类型 Azure AI 搜索字段类型
Bool Edm.Boolean、Edm.String
类似于整数的数字 Edm.Int32、Edm.Int64、Edm.String
类似于浮点的数字 Edm.Double、Edm.String
String Edm.String
基元类型的数组,如 ["a", "b", "c"] 集合 (Edm.String)
类似于日期的字符串 Edm.DateTimeOffset、Edm.String
GeoJSON 对象,如 { "type": "Point", "coordinates": [long, lat] } Edm.GeographyPoint
其他 JSON 对象 不可用

配置和运行 Azure Cosmos DB 索引器

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

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

    POST https://[service name].search.azure.cn/indexers?api-version=2024-05-01-preview
    Content-Type: application/json
    api-key: [search service admin key]
    {
        "name" : "[my-cosmosdb-indexer]",
        "dataSourceName" : "[my-cosmosdb-gremlin-ds]",
        "targetIndexName" : "[my-search-index]",
        "disabled": null,
        "schedule": null,
        "parameters": {
            "batchSize": null,
            "maxFailedItems": 0,
            "maxFailedItemsPerBatch": 0,
            "base64EncodeKeys": false,
            "configuration": {}
            },
        "fieldMappings": [],
        "encryptionKey": null
    }
    
  2. 如果字段名称或类型存在差异,或者需要在搜索索引中使用多个版本的源字段,请指定字段映射

  3. 有关其他属性的详细信息,请参阅创建索引器

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

检查索引器状态

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

GET https://myservice.search.azure.cn/indexers/myindexer/status?api-version=2024-05-01-preview
  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 个最近完成的执行,它们按时间倒序排列,这样最新的执行最先显示。

为新文档和已更改的文档编制索引

索引器完全填充搜索索引后,建议运行后续的索引器,以便仅对数据库中的新文档和已更改的文档进行增量索引编制。

若要启用增量索引编制,请在数据源定义中设置“dataChangeDetectionPolicy”属性。 此属性告知索引器对数据使用哪种更改跟踪机制。

对于 Azure Cosmos DB 索引器,唯一支持的策略是使用 Azure Cosmos DB 提供的 _ts(时间戳)属性的 HighWaterMarkChangeDetectionPolicy

以下示例演示具有更改检测策略的数据源定义

"dataChangeDetectionPolicy": {
    "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
"  highWaterMarkColumnName": "_ts"
},

为已删除的文档编制索引

删除图形数据后,可能还需要从搜索索引中删除其相应的文档。 数据删除保护策略的目的是有效识别已删除的数据项,并删除索引中的完整文档。 数据删除检测策略并不是要删除部分文档信息。 目前,唯一支持的策略是 Soft Delete 策略(删除标记有某种标志),它在数据源定义中指定如下:

"dataDeletionDetectionPolicy"": {
    "@odata.type" : "#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",
    "softDeleteColumnName" : "the property that specifies whether a document was deleted",
    "softDeleteMarkerValue" : "the value that identifies a document as deleted"
}

下面的示例创建具有软删除策略的数据源:

POST https://[service name].search.azure.cn/datasources?api-version=2024-05-01-preview
Content-Type: application/json
api-key: [Search service admin key]

{
    "name": "[my-cosmosdb-gremlin-ds]",
    "type": "cosmosdb",
    "credentials": {
        "connectionString": "AccountEndpoint=https://[cosmos-account-name].documents.azure.cn;AccountKey=[cosmos-account-key];Database=[cosmos-database-name];ApiKind=Gremlin"
    },
    "container": { "name": "[my-cosmos-collection]" },
    "dataChangeDetectionPolicy": {
        "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
        "highWaterMarkColumnName": "`_ts`"
    },
    "dataDeletionDetectionPolicy": {
        "@odata.type": "#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",
        "softDeleteColumnName": "isDeleted",
        "softDeleteMarkerValue": "true"
    }
}

即使启用删除检测策略,也不支持从索引中删除复杂的 (Edm.ComplexType) 字段。 此策略要求 Gremlin 数据库中的“活动”列的类型为整数、字符串或布尔值。

将图形数据映射到搜索索引中的字段

Azure Cosmos DB for Apache Gremlin 索引器自动映射几段图形数据:

  1. 索引器会将 _rid 映射到索引器中的 rid 字段(如果存在),并对其进行 Base64 编码。

  2. 索引器会将 _id 映射到索引器中的 id 字段(如果存在)。

  3. 在使用 Azure Cosmos DB for Apache Gremlin 查询 Azure Cosmos DB 数据库时,你可能会注意到,每个属性的 JSON 输出都具有 idvalue。 索引器会自动将属性 value 映射到搜索索引中与属性同名的字段(如果存在)。 在下面的示例中,450 将映射到搜索索引中的 pages 字段。

    {
        "id": "Cookbook",
        "label": "book",
        "type": "vertex",
        "properties": {
          "pages": [
            {
              "id": "48cf6285-a145-42c8-a0aa-d39079277b71",
              "value": "450"
            }
          ]
        }
    }

你可能会发现,为了将查询输出映射到索引中的字段,需要使用输出字段映射。 你可能需要使用输出字段映射,而不是字段映射,因为自定义查询可能具有复杂的数据。

例如,假设查询生成以下输出:

    [
      {
        "vertex": {
          "id": "Cookbook",
          "label": "book",
          "type": "vertex",
          "properties": {
            "pages": [
              {
                "id": "48cf6085-a211-42d8-a8ea-d38642987a71",
                "value": "450"
              }
            ],
          }
        },
        "written_by": [
          {
            "yearStarted": "2017"
          }
        ]
      }
    ]

如果要将上述 JSON 中的 pages 值映射到索引中的 totalpages 字段,可以将以下pages添加到索引器定义:

    ... // rest of indexer definition 
    "outputFieldMappings": [
        {
          "sourceFieldName": "/document/vertex/pages",
          "targetFieldName": "totalpages"
        }
    ]

请注意输出字段映射如何以 /document 开头,并且不包括对 JSON 中属性键的引用。 这是因为索引器会在引入关系图数据时将每个文档放置在 /document 节点下,并且索引器还自动让你能够引用 pages 的值,方式是直接引用 pages,而不必引用 pages 数组中的第一个对象。

后续步骤