Importar dados do Azure Cosmos DB for Apache Gremlin para consultas na Pesquisa de IA do Azure

Importante

O indexador do Azure Cosmos DB for Apache Gremlin está em versão prévia pública sob os Termos de Uso Complementares. No momento, não há suporte a SDK.

Neste artigo, aprenda como configurar um indexador que importa o conteúdo do Azure Cosmos DB for Apache Gremlin e o torna pesquisável no Azure AI Search.

Este artigo complementa o artigo Criar um indexador com informações específicas do Cosmos DB. Ele usa as APIs REST para demonstrar um fluxo de trabalho de três partes comum a todos os indexadores: criar uma fonte de dados, criar um índice e criar um indexador. A extração de dados ocorre quando você envia a solicitação Criar Indexador.

Como a terminologia pode ser confusa, vale a pena observar que a indexação do Azure Cosmos DB e a indexação do Azure AI Search são operações diferentes. A indexação no Azure AI Search cria e carrega um índice de pesquisa em seu serviço de pesquisa.

Pré-requisitos

Definir a fonte de dados

A definição da fonte de dados especifica os dados a serem indexados, as credenciais e as políticas para identificar alterações nos dados. Uma fonte de dados é definida como um recurso independente para que possa ser usada por vários indexadores.

Para essa chamada, especifique uma versão prévia da API REST para criar uma fonte de dados que se conecte por meio de um Azure Cosmos DB for Apache Gremlin. Você pode usar 2021-04-01-versão prévia ou posterior. Recomendamos a API de visualização mais recente.

  1. Crie ou atualize uma fonte de dados para configurar sua definição:

     POST https://[service name].search.windows.net/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.com;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. Defina "type" como "cosmosdb" (obrigatório).

  3. Defina "credentials" como a cadeia de conexão. A próxima seção descreve os formatos compatíveis.

  4. Defina "container" como a coleção. A propriedade "name" é necessária e especifica a ID do grafo.

    A propriedade "query" é opcional. Por padrão, o indexador do Azure AI Search para o Azure Cosmos DB for Apache Gremlin faz com que todos os vértices do grafo sejam um documento no índice. As bordas serão ignoradas. O padrão de consulta é g.V(). Como alternativa, você pode definir a consulta para indexar apenas as bordas. Para indexar as bordas, defina a consulta como g.E().

  5. Defina "dataChangeDetectionPolicy" se os dados forem voláteis e você quiser que o indexador selecione apenas os itens novos e atualizados nas execuções seguintes. O progresso incremental será habilitado por padrão usando _ts como a coluna de marca d' água alta.

  6. Defina "dataDeletionDetectionPolicy" se desejar remover documentos de pesquisa de um índice de pesquisa quando o item de origem for excluído.

Credenciais e cadeias de conexão com suporte

Os indexadores podem se conectar a uma coleção usando as conexões a seguir. Para conexões direcionadas ao Azure Cosmos DB for Apache Gremlin, inclua "ApiKind" na cadeia de conexão.

Evite usar números de porta na URL do ponto de extremidade. Se você incluir o número da porta, a conexão falhará.

Cadeia de conexão de acesso completo
{ "connectionString" : "AccountEndpoint=https://<Cosmos DB account name>.documents.azure.com;AccountKey=<Cosmos DB auth key>;Database=<Cosmos DB database id>;ApiKind=MongoDb" }
Obtenha a cadeia de conexão na página da conta do Azure Cosmos DB no portal do Azure selecionando Chaves no painel de navegação à esquerda. Você deve selecionar uma cadeia de conexão completa, não apenas uma chave.
Cadeia de conexão de identidade gerenciada
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.DocumentDB/databaseAccounts/<your cosmos db account name>/;(ApiKind=[api-kind];)" }
Essa cadeia de conexão não exige uma chave de conta, mas você precisa ter configurado anteriormente um serviço de pesquisa para se conectar usando uma identidade gerenciada e ter criado uma atribuição de função que conceda permissões de Função de Leitor de Conta do Cosmos DB. Confira Configurar uma conexão do indexador com um banco de dados do Azure Cosmos DB usando uma identidade gerenciada para saber mais.

Adicionar campos de pesquisa a um índice

Em um índice de pesquisa, adicione campos para aceitar os documentos JSON de origem ou a saída da projeção de consulta personalizada. Verifique se o esquema de índice de pesquisa é compatível com o seu grafo. Para o conteúdo no Azure Cosmos DB, o esquema de índice de pesquisa deve corresponder aos itens do Azure Cosmos DB na fonte de dados.

  1. Crie ou atualize um índice para definir os campos de pesquisa que armazenarão os dados:

     POST https://[service name].search.windows.net/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. Crie um campo de chave do documento ("key": true). Para coleções particionadas, a chave de documento padrão é a propriedade _rid do Azure Cosmos DB, que o Azure AI Search renomeia automaticamente para rid porque os nomes de campo não podem começar com um caractere de sublinhado. Além disso, os valores _rid do Azure Cosmos DB contêm caracteres que são inválidos nos termos do Azure AI Search. Por esse motivo, os valores _rid são codificados em Base64.

  3. Crie campos adicionais para obter um conteúdo mais pesquisável. Confira Criar um índice para obter detalhes.

Mapeamento de tipos de dados

Tipo de dados JSON Tipos de campo do Azure AI Search
Bool Edm.Boolean, Edm.String
Números que se parecem com inteiros Edm.Int32, Edm.Int64, Edm.String
Números que se parecem com pontos flutuantes Edm.Double, Edm.String
String Edm.String
Matrizes de tipos primitivos, como ["a", "b" e "c"] Collection(Edm.String)
Cadeias de caracteres que se parecem com datas Edm.DateTimeOffset, Edm.String
Objetos GeoJSON, por exemplo, { "type": "Point", "coordinates": [long, lat] } Edm.GeographyPoint
Outros objetos JSON N/D

Configurar e executar o indexador do Azure Cosmos DB

Uma vez que o índice e a fonte de dados forem criados, será possível criar o indexador. A configuração do indexador especifica as entradas, os parâmetros e as propriedades que controlam os comportamentos de tempo de execução.

  1. Crie ou atualize um indexador dando um nome a ele e referenciando a fonte de dados e o índice de destino:

    POST https://[service name].search.windows.net/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. Especifique mapeamentos de campo se houver diferenças no nome ou tipo de campo, ou se você precisar de várias versões de um campo de origem no índice de pesquisa.

  3. Confira Criar um indexador para obter mais informações sobre outras propriedades.

Um indexador é executado automaticamente depois de criado. Você pode evitar isso definindo "desabilitado" como verdadeiro. Para controlar a execução do indexador, execute um indexador sob demanda ou coloque-o em um agendamento.

Checar o status do indexador

Para monitorar o histórico de execuções e o status do indexador, envie uma solicitação Obter Status do Indexador:

GET https://myservice.search.windows.net/indexers/myindexer/status?api-version=2024-05-01-preview
  Content-Type: application/json  
  api-key: [admin key]

A resposta inclui o status e o número de itens processados. Ela deve ser parecida com o seguinte exemplo:

    {
        "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
        ]
    }

O histórico de execuções contém até 50 execuções mais recentes, classificadas em ordem cronológica inversa, de modo que a execução mais recente apareça em primeiro lugar.

Como indexar documentos novos e alterados

Depois que um indexador preencher completamente um índice de pesquisa, o ideal será que o indexador seguinte seja executado para indexar de maneira incremental apenas os documentos novos e alterados no banco de dados.

Para habilitar a indexação incremental, defina a propriedade "dataChangeDetectionPolicy" na definição da fonte de dados. Essa propriedade informa o indexador de que o mecanismo de controle de alterações é usado nos dados.

Para indexadores do Azure Cosmos DB, a única política com suporte é a HighWaterMarkChangeDetectionPolicy que usa a propriedade _ts (carimbo de data/hora) fornecida pelo Azure Cosmos DB.

O seguinte exemplo mostra uma definição de fonte de dados com uma política de detecção de alteração:

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

Indexando documentos excluídos

Quando os dados do grafo forem excluídos, você pode excluir também o documento correspondente do índice de pesquisa. A finalidade de uma política de detecção de exclusão de dados é identificar com eficiência os itens de dados excluídos e excluir o documento completo do índice. A política de detecção de exclusão de dados não é destinada a excluir informações de documento parcial. Atualmente, a única política com suporte é a política Soft Delete (a exclusão recebe algum tipo de marcador), que é especificada na definição de fonte de dados da seguinte forma:

"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"
}

O seguinte exemplo cria uma fonte de dados com uma política de exclusão reversível:

POST https://[service name].search.windows.net/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.com;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"
    }
}

Mesmo se você habilitar a política de detecção de exclusão, a exclusão campos complexos (Edm.ComplexType) do índice não terá suporte. Essa política exige que a coluna 'ativa' no banco de dados Gremlin seja do tipo inteiro, cadeia de caracteres ou booliano.

Mapear dados de grafo para campos em um índice de pesquisa

O indexador do Azure Cosmos DB for Apache Gremlin mapeará automaticamente algumas partes dos dados do grafo:

  1. O indexador irá mapear _rid para um campo rid no índice, se ele existir e codificá-lo em Base64.

  2. O indexador será mapeado _id para um id campo no índice, se ele existir.

  3. Ao consultar o banco de dados do Azure Cosmos DB usando o Azure Cosmos DB for Apache Gremlin, você pode observar que a saída JSON de cada propriedade tem um id e um value. O indexador mapeará automaticamente as propriedades value um campo no seu índice de pesquisa que tenha o mesmo nome da propriedade, se ela existir. No exemplo a seguir, 450 seria mapeado para um pages campo no índice de pesquisa.

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

Você pode precisar usar mapeamentos de campo de saída para mapear a saída da consulta para os campos no índice. Você provavelmente vai usar mapeamentos de campo de saída em vez de mapeamentos de campo, pois a consulta personalizada provavelmente terá dados complexos.

Por exemplo, digamos que sua consulta produza esta saída:

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

Se você quiser mapear o valor de pages no JSON acima para um totalpages campo em seu índice, poderá adicionar o seguinte mapeamento de campo de saída à sua definição de indexador:

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

Observe como o mapeamento do campo de saída começa com /document e não inclui uma referência à chave de propriedades no JSON. Isso ocorre porque o indexador coloca cada documento sob o nó /document ao ingerir os dados do grafo e o indexador também permite que você faça referência automaticamente ao valor de pages referência simples pages, em vez de ter que referenciar o primeiro objeto na matriz de pages.

Próximas etapas