Indexación de datos de Azure Cosmos DB mediante SQL API

En este artículo, aprenderá a configurar un indexador que importa contenido mediante la API de SQL de Azure Cosmos DB.

Este artículo complementa al artículo Creación de indexadores en Azure Cognitive Search con información específica de SQL API de Cosmos DB. Usa las API REST para mostrar un flujo de trabajo de tres partes común a todos los indexadores: crear un origen de datos, crear un índice y crear un indexador. La extracción de datos se produce cuando se envía la solicitud para crear un indexador.

Dado que la terminología puede ser confusa, merece la pena tener en cuenta que la indexación de Cosmos DB y la indexación de Cognitive Search son operaciones diferentes. La indexación en Cognitive Search crea y carga un índice de búsqueda en el servicio de búsqueda.

Requisitos previos

Definición del origen de datos

La definición del origen de datos especifica los datos que se indexan, las credenciales y las directivas para identificar los cambios en los datos. Un origen de datos se define como un recurso independiente para que puedan usarlo varios indexadores.

  1. Cree o actualice un origen de datos para establecer su definición:

    POST https://[service name].search.windows.net/datasources?api-version=2020-06-30
    Content-Type: application/json
    api-key: [Search service admin key]
    {
        "name": "[my-cosmosdb-ds]",
        "type": "cosmosdb",
        "credentials": {
          "connectionString": "AccountEndpoint=https://[cosmos-account-name].documents.azure.com;AccountKey=[cosmos-account-key];Database=[cosmos-database-name]"
        },
        "container": {
          "name": "[my-cosmos-db-collection]",
          "query": null
        },
        "dataChangeDetectionPolicy": {
          "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
        "  highWaterMarkColumnName": "_ts"
        },
        "dataDeletionDetectionPolicy": null,
        "encryptionKey": null,
        "identity": null
    }
    
  2. Establezca "type" en "cosmosdb" (obligatorio). Si usa una versión de la API de búsqueda anterior a la 2017-11-11, la sintaxis del elemento "type" es "documentdb". De lo contrario, para la versión 2019-05-06 y versiones posteriores, use "cosmosdb".

  3. Establezca el elemento "credentials" en una cadena de conexión. En la sección siguiente se describen los formatos admitidos.

  4. Establezca "container" en la colección. La propiedad "name" es necesaria y especifica el identificador de la colección de base de datos que se va a indexar. La propiedad "query" es opcional. Utilícela para aplanar un documento JSON arbitrario en un esquema plano que Azure Cognitive Search pueda indexar.

  5. Establezca el elemento "dataChangeDetectionPolicy" si los datos son volátiles y desea que el indexador seleccione solo los elementos nuevos y actualizados en ejecuciones posteriores.

  6. Establezca "dataDeletionDetectionPolicy" si desea quitar documentos de búsqueda de un índice de búsqueda cuando se elimine el elemento de origen.

Credenciales y cadenas de conexión admitidas

Los indexadores se pueden conectar a una colección mediante las siguientes conexiones. Para las conexiones tienen como destino SQL API, puede omitir el elemento "ApiKind" de la cadena de conexión.

Evite los números de puerto en la dirección URL del punto de conexión. Si incluye el número de puerto, se producirá un error en la conexión.

Cadena de conexión de acceso completo
{ "connectionString" : "AccountEndpoint=https://<Cosmos DB account name>.documents.azure.com;AccountKey=<Cosmos DB auth key>;Database=<Cosmos DB database id>" }`
Para obtener la cadena de conexión de la página de la cuenta de Cosmos DB en Azure Portal, seleccione Claves en el panel de navegación izquierdo. Asegúrese de seleccionar una cadena de conexión completa y no solo una clave.
Cadena de conexión de identidad administrada
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.DocumentDB/databaseAccounts/<your cosmos db account name>/;(ApiKind=[api-kind];)" }
Esta cadena de conexión no requiere una clave de cuenta, pero debe haber configurado previamente un servicio de búsqueda para conectarse mediante una identidad administrada y haber creado una asignación de roles que conceda permisos de rol de lector de cuentas de Cosmos DB. Consulte Configuración de una conexión de indexador a una base de datos de Cosmos DB mediante una identidad administrada para más información.

Uso de consultas para dar forma a los datos indizados

En la propiedad "query" del elemento "container", puede especificar una consulta SQL para aplanar las propiedades o matrices anidadas y de las propiedades JSON del proyecto, y para filtrar los datos que se van a indexar.

Documento de ejemplo:

    {
        "userId": 10001,
        "contact": {
            "firstName": "andy",
            "lastName": "hoh"
        },
        "company": "microsoft",
        "tags": ["azure", "cosmosdb", "search"]
    }

Consulta de filtro:

SELECT * FROM c WHERE c.company = "microsoft" and c._ts >= @HighWaterMark ORDER BY c._ts

Consulta sin formato:

SELECT c.id, c.userId, c.contact.firstName, c.contact.lastName, c.company, c._ts FROM c WHERE c._ts >= @HighWaterMark ORDER BY c._ts

Consulta de proyección:

SELECT VALUE { "id":c.id, "Name":c.contact.firstName, "Company":c.company, "_ts":c._ts } FROM c WHERE c._ts >= @HighWaterMark ORDER BY c._ts

Consulta sin formato de matriz:

SELECT c.id, c.userId, tag, c._ts FROM c JOIN tag IN c.tags WHERE c._ts >= @HighWaterMark ORDER BY c._ts

Consultas no admitidas (DISTINCT y GROUP BY)

No se admiten las consultas en las que se usan la palabra clave DISTINCT o la cláusula GROUP BY. Azure Cognitive Search se basa en la paginación de consultas SQL para enumerar la totalidad de los resultados de la consulta. Ni la palabra clave DISTINCT ni las cláusulas GROUP BY son compatibles con los tokens de continuación que se usan para paginar los resultados.

Ejemplos de consultas no admitidas:

SELECT DISTINCT c.id, c.userId, c._ts FROM c WHERE c._ts >= @HighWaterMark ORDER BY c._ts

SELECT DISTINCT VALUE c.name FROM c ORDER BY c.name

SELECT TOP 4 COUNT(1) AS foodGroupCount, f.foodGroup FROM Food f GROUP BY f.foodGroup

Aunque Cosmos DB tiene una solución alternativa para admitir la paginación de consultas SQL con la palabra clave DISTINCT mediante la cláusula ORDER BY, no es compatible con Azure Cognitive Search. La consulta devolverá un único valor JSON, mientras que Azure Cognitive Search espera un objeto JSON.

-- The following query returns a single JSON value and isn't supported by Azure Cognitive Search
SELECT DISTINCT VALUE c.name FROM c ORDER BY c.name

Adición de campos de búsqueda a un índice

En un índice de búsqueda, agregue campos para aceptar los documentos JSON de origen o la salida de la proyección de consulta personalizada. Asegúrese de que el esquema del índice de búsqueda sea compatible con los datos de origen. Para el contenido de Cosmos DB, el esquema del índice de búsqueda debe corresponder a los elementos de Azure Cosmos DB del origen de datos.

  1. Cree o actualice un índice para definir campos de búsqueda que almacenarán los datos:

    POST https://[service name].search.windows.net/indexes?api-version=2020-06-30
    Content-Type: application/json
    api-key: [Search service admin key]
    {
        "name": "mysearchindex",
        "fields": [{
            "name": "rid",
            "type": "Edm.String",
            "key": true,
            "searchable": false
        }, 
        {
            "name": "description",
            "type": "Edm.String",
            "filterable": false,
            "searchable": true,
            "sortable": false,
            "facetable": false,
            "suggestions": true
        }
      ]
    }
    
  2. Cree un campo de clave de documento ("key": true). En el caso de las colecciones con particiones, la clave de documento predeterminada es la propiedad _rid de Azure Cosmos DB, a la que Azure Cognitive Search cambia el nombre automáticamente a rid, porque los nombres de los campos no pueden comenzar por un carácter de guion bajo. Además, los valores _rid de Azure Cosmos DB contienen caracteres que no son válidos en las claves de Azure Cognitive Search. Por este motivo, la _rid valores están codificados con Base64.

  3. Cree campos adicionales para obtener más contenido que se puede buscar. Consulte Creación de un índice para obtener más información.

Asignación de tipos de datos

Tipos de datos JSON Tipos de campos de Cognitive Search
Bool Edm.Boolean, Edm.String
Números que parecen enteros Edm.Int32, Edm.Int64, Edm.String
Números que parecen puntos flotantes Edm.Double, Edm.String
String Edm.String
Matrices de tipos primitivos, como ["a", "b", "c"] Collection(Edm.String)
Cadenas que parecen fechas Edm.DateTimeOffset, Edm.String
Objetos GeoJSON, como { "type": "Point", "coordinates": [long, lat] } Edm.GeographyPoint
Otros objetos JSON N/D

Configuración y ejecución del indexador de Cosmos DB

Una vez creados el origen de datos y los índices, podrá crear el indexador: La configuración del indexador especifica las entradas, los parámetros y las propiedades que controlan los comportamientos en tiempo de ejecución.

  1. Cree o actualice un indexador asignándole un nombre y haciendo referencia al índice de origen y destino de datos:

    POST https://[service name].search.windows.net/indexers?api-version=2020-06-30
    Content-Type: application/json
    api-key: [search service admin key]
    {
        "name" : "[my-cosmosdb-indexer]",
        "dataSourceName" : "[my-cosmosdb-ds]",
        "targetIndexName" : "[my-search-index]",
        "disabled": null,
        "schedule": null,
        "parameters": {
            "batchSize": null,
            "maxFailedItems": 0,
            "maxFailedItemsPerBatch": 0,
            "base64EncodeKeys": false,
            "configuration": {}
            },
        "fieldMappings": [],
        "encryptionKey": null
    }
    
  2. Especifique asignaciones de campos si hay diferencias en el nombre o el tipo de campo, o si necesita varias versiones de un campo de origen en el índice de búsqueda.

  3. Consulte Creación de un indexador para más información sobre otras propiedades.

Un indexador se ejecuta automáticamente cuando se crea. Puede evitarlo estableciendo el valor de "disabled" en true. Para controlar la ejecución del indexador, ejecute un indexador a petición o prográmelo.

Comprobación del estado del indexador

Para supervisar el estado del indexador y el historial de ejecución, envíe una solicitud para Obtener el estado del indexador:

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

La respuesta incluye el estado y el número de elementos procesados. Debe tener un aspecto similar al siguiente ejemplo:

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

El historial de ejecución contiene como máximo las 50 ejecuciones completadas más recientemente en orden cronológico inverso (la ejecución más reciente aparece en primer lugar).

Indexación de documentos nuevos y modificados

Una vez que un indexador ha rellenado por completo un índice de búsqueda, es posible que quiera que las ejecuciones posteriores del indexador indexen incrementalmente solo los documentos nuevos y modificados de la base de datos.

Para habilitar la indexación incremental, establezca la propiedad "dataChangeDetectionPolicy" en la definición del origen de datos. Esta propiedad indica al indexador qué mecanismo de seguimiento de cambios se usa en los datos.

En el caso de los indexadores de Cosmos DB, la única directiva compatible es HighWaterMarkChangeDetectionPolicy que usa la propiedad _ts (marca de tiempo) que proporciona Azure Cosmos DB.

En el ejemplo siguiente, se muestra una definición de origen de datos con una directiva de detección de cambios:

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

Indexación incremental y consultas personalizadas

Si usa una consulta personalizada para recuperar documentos, asegúrese de que la consulta ordene los resultados por la columna _ts. Esto permite la creación de puntos de comprobación, que Azure Cognitive Search usa para proporcionar el progreso incremental en presencia de errores.

En algunos casos, incluso si la consulta contiene una cláusula ORDER BY [collection alias]._ts, Azure Cognitive Search puede no deducir que la consulta se ordene por _ts. Puede indicar a Azure Cognitive Search que los resultados están ordenados; para ello, establezca la propiedad de configuración assumeOrderByHighWaterMarkColumn.

Para especificar esta sugerencia, cree o actualice la definición del indexador como se indica a continuación:

{
    ... other indexer definition properties
    "parameters" : {
        "configuration" : { "assumeOrderByHighWaterMarkColumn" : true } }
} 

Indexación de documentos eliminados

Cuando se eliminan filas de la recopilación, lo habitual es que también se deseen eliminar del índice de búsqueda. El fin de una directiva de detección de eliminación de datos es identificar eficazmente los elementos de datos eliminados. Actualmente, solo se admite la directiva Soft Delete (la eliminación se indica con algún tipo de marca), especificada de la siguiente forma en el origen de datos:

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

Si usa una consulta personalizada, asegúrese de que la consulta proyecta la propiedad a la que hace referencia softDeleteColumnName.

En el ejemplo siguiente se crea un origen de datos con una directiva de eliminación temporal:

POST https://[service name].search.windows.net/datasources?api-version=2020-06-30
Content-Type: application/json
api-key: [Search service admin key]

{
    "name": "[my-cosmosdb-ds]",
    "type": "cosmosdb",
    "credentials": {
        "connectionString": "AccountEndpoint=https://[cosmos-account-name].documents.azure.com;AccountKey=[cosmos-account-key];Database=[cosmos-database-name]"
    },
    "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"
    }
}

Uso de .NET

Para los datos a los que se accede mediante el protocolo de SQL API, puede usar el SDK de .NET para la automatización con indexadores. Se recomienda que revise la secciones anteriores sobre la API REST para obtener información sobre los conceptos, el flujo de trabajo y los requisitos. A continuación, puede consultar la siguiente documentación de referencia de la API de .NET para implementar un indexador JSON en código administrado:

Pasos siguientes

Ahora puede controlar cómo ejecutar el indexador, supervisar el estado o programar la ejecución del indexador. Los siguientes artículos se aplican a los indexadores que extraen contenido de Azure Cosmos DB: