Indicizzare i dati da Azure Cosmos DB per NoSQL per le query in Ricerca di intelligenza artificiale di Azure

Questo articolo illustra come configurare un indicizzatore che importa il contenuto da Azure Cosmos DB per NoSQL e lo rende ricercabile in Ricerca di intelligenza artificiale di Azure.

Questo articolo integra l'articolo Creare un indicizzatore con informazioni specifiche di Cosmos DB. Usa le API REST per illustrare un flusso di lavoro in tre parti comune a tutti gli indicizzatori: creare un'origine dati, creare un indice, creare un indicizzatore. L'estrazione dei dati si verifica quando si invia la richiesta Crea indicizzatore.

Poiché la terminologia può confondere, vale la pena notare che l'indicizzazione di Azure Cosmos DB e l'indicizzazione di Ricerca di intelligenza artificiale di Azure sono operazioni diverse. L'indicizzazione in Ricerca di intelligenza artificiale di Azure crea e carica un indice di ricerca nel servizio di ricerca.

Prerequisiti

  • Un account, un database, un contenitore e elementi di Azure Cosmos DB. Usare la stessa area sia per Ricerca di intelligenza artificiale di Azure che per Azure Cosmos DB per ridurre la latenza ed evitare addebiti per la larghezza di banda.

  • Un criterio di indicizzazione automatico nella raccolta di Azure Cosmos DB, impostato su Coerente. Questa è la configurazione predefinita. L'indicizzazione differita non è consigliata e può comportare dati mancanti.

  • Autorizzazioni di lettura. Un stringa di connessione "accesso completo" include una chiave che concede l'accesso al contenuto, ma se si usa il controllo degli accessi in base al ruolo di Azure (Microsoft Entra ID), assicurarsi che all'identità gestita del servizio di ricerca siano assegnati sia il ruolo lettore dell'account Cosmos DB che il ruolo lettore dati predefinito di Cosmos DB.

  • Client REST per creare l'origine dati, l'indice e l'indicizzatore.

Definire l'origine dati

La definizione dell'origine dati specifica i dati da indicizzare, credenziali e criteri per identificare le modifiche nei dati. Un'origine dati è una risorsa indipendente che può essere usata da più indicizzatori.

  1. Creare o aggiornare un'origine dati per impostarne la definizione:

    POST https://[service name].search.windows.net/datasources?api-version=2023-11-01
    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. Impostare "type" su "cosmosdb" (obbligatorio). Se si usa un'API di ricerca precedente versione 2017-11-11, la sintassi per "type" è "documentdb". In caso contrario, per 2019-05-06 e versioni successive, usare "cosmosdb".

  3. Impostare "credentials" su un stringa di connessione. Nella sezione successiva vengono descritti i formati supportati.

  4. Impostare "container" sulla raccolta. La proprietà "name" è obbligatoria e specifica l'ID della raccolta di database da indicizzare. La proprietà "query" è facoltativa. Usarlo per rendere flat un documento JSON arbitrario in uno schema flat che Ricerca di intelligenza artificiale di Azure può indicizzare.

  5. Impostare "dataChangeDetectionPolicy" se i dati sono volatili e si vuole che l'indicizzatore rilevi solo gli elementi nuovi e aggiornati nelle esecuzioni successive.

  6. Impostare "dataDeletionDetectionPolicy" se si desidera rimuovere i documenti di ricerca da un indice di ricerca quando l'elemento di origine viene eliminato.

Credenziali supportate e stringa di connessione

Gli indicizzatori possono connettersi a una raccolta usando le connessioni seguenti.

Evitare numeri di porta nell'URL dell'endpoint. Se si include il numero di porta, la connessione avrà esito negativo.

Accesso completo stringa di connessione
{ "connectionString" : "AccountEndpoint=https://<Cosmos DB account name>.documents.azure.com;AccountKey=<Cosmos DB auth key>;Database=<Cosmos DB database id>" }'
È possibile ottenere il stringa di connessione dalla pagina dell'account Azure Cosmos DB nel portale di Azure selezionando Chiavi nel riquadro di spostamento a sinistra. Assicurarsi di selezionare un stringa di connessione completo e non solo una chiave.
Identità gestita stringa di connessione
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.DocumentDB/databaseAccounts/<your cosmos db account name>/;(ApiKind=[api-kind];)/(IdentityAuthType=[identity-auth-type])" }
Questo stringa di connessione non richiede una chiave dell'account, ma è necessario disporre di un servizio di ricerca in grado di connettersi usando un'identità gestita. Per le connessioni destinate all'API SQL, è possibile omettere ApiKind dal stringa di connessione. Per altre informazioni su ApiKind, IdentityAuthType vedere Configurazione di una connessione dell'indicizzatore a un database di Azure Cosmos DB tramite un'identità gestita.

Utilizzo di query per formare dati indicizzati

Nella proprietà "query" in "contenitore" è possibile specificare una query SQL per rendere flat le proprietà o le matrici annidate, le proprietà JSON del progetto e filtrare i dati da indicizzare.

Documento di esempio:

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

Query di filtro:

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

Query di appiattimento:

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

Query di proiezione:

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

Query di appiattimento matrici:

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

Query non supportate (DISTINCT e GROUP BY)

Le query che usano la parola chiave DISTINCT o la clausola GROUP BY non sono supportate. Ricerca di intelligenza artificiale di Azure si basa sulla paginazione di query SQL per enumerare completamente i risultati della query. Nessuna delle clausole DISTINCT o GROUP BY è compatibile con i token di continuazione usati per impaginare i risultati.

Esempi di query non supportate:

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

Anche se Azure Cosmos DB offre una soluzione alternativa per supportare la paginazione di query SQL con la parola chiave DISTINCT usando la clausola ORDER BY, non è compatibile con Ricerca di intelligenza artificiale di Azure. La query restituisce un singolo valore JSON, mentre Ricerca di intelligenza artificiale di Azure prevede un oggetto JSON.

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

Aggiungere campi di ricerca a un indice

In un indice di ricerca aggiungere campi per accettare i documenti JSON di origine o l'output della proiezione di query personalizzata. Verificare che lo schema dell'indice di ricerca sia compatibile con i dati di origine. Per il contenuto in Azure Cosmos DB, lo schema dell'indice di ricerca deve corrispondere agli elementi di Azure Cosmos DB nell'origine dati.

  1. Creare o aggiornare un indice per definire i campi di ricerca in cui sono archiviati i dati:

    POST https://[service name].search.windows.net/indexes?api-version=2023-11-01
    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. Creare un campo chiave documento ("chiave": true). Per le raccolte partizionate, la chiave del documento predefinita è la proprietà di Azure Cosmos DB _rid , che Ricerca intelligenza artificiale di Azure rinomina automaticamente in rid perché i nomi dei campi non possono iniziare con un carattere di sottolineatura. I valori di Azure Cosmos DB _rid contengono anche caratteri non validi nelle chiavi di Ricerca di intelligenza artificiale di Azure. Per questo motivo, i valori _rid presentano la codificata Base64.

  3. Creare altri campi per un contenuto più ricercabile. Per informazioni dettagliate, vedere Creare un indice .

Mapping dei tipi di dati

Tipi di dati JSON Tipi di campo di Ricerca intelligenza artificiale di Azure
Bool Edm.Boolean, Edm.String
Numeri che rappresentano numeri interi Edm.Int32, Edm.Int64, Edm.String
Numeri che rappresentano numeri a virgola mobile Edm.Double, Edm.String
String Edm.String
Matrici di tipi primitivi come ["a", "b", "c"] Collection(Edm.String)
Stringhe che rappresentano date Edm.DateTimeOffset, Edm.String
Oggetti GeoJSON come { "type": "Point", "coordinates": [long, lat] } Edm.GeographyPoint
Altri oggetti JSON N/D

Configurare ed eseguire l'indicizzatore Azure Cosmos DB per NoSQL

Dopo aver creato l'indice e l'origine dati, è possibile creare l'indicizzatore. La configurazione dell'indicizzatore specifica gli input, i parametri e le proprietà che controllano i comportamenti di runtime.

  1. Creare o aggiornare un indicizzatore assegnando un nome e facendo riferimento all'origine dati e all'indice di destinazione:

    POST https://[service name].search.windows.net/indexers?api-version=2023-11-01
    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. Specificare i mapping dei campi se sono presenti differenze nel nome o nel tipo di campo o se sono necessarie più versioni di un campo di origine nell'indice di ricerca.

  3. Per altre informazioni sulle altre proprietà, vedere Creare un indicizzatore .

Un indicizzatore viene eseguito automaticamente quando viene creato. È possibile evitare questo problema impostando "disabilitato" su true. Per controllare l'esecuzione dell'indicizzatore, eseguire un indicizzatore su richiesta o inserirlo in una pianificazione.

Controllare lo stato dell'indicizzatore

Per monitorare lo stato dell'indicizzatore e la cronologia di esecuzione, inviare una richiesta Get Indexer Status :To monitor the indexer status and execution history, send a Get Indexer Status request:

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

La risposta include lo stato e il numero di elementi elaborati. Dovrebbe essere simile all'esempio seguente:

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

La cronologia di esecuzione contiene fino a 50 delle esecuzioni completate più di recente, ordinate in ordine cronologico inverso in modo che l'esecuzione più recente venga prima.

Indicizzazione di documenti nuovi e modificati

Dopo che un indicizzatore ha popolato completamente un indice di ricerca, è possibile che l'indicizzatore successivo venga eseguito per indicizzare in modo incrementale solo i documenti nuovi e modificati nel database.

Per abilitare l'indicizzazione incrementale, impostare la proprietà "dataChangeDetectionPolicy" nella definizione dell'origine dati. Questa proprietà indica all'indicizzatore quale meccanismo di rilevamento delle modifiche viene usato sui dati.

Per gli indicizzatori di Azure Cosmos DB, l'unico criterio supportato è l'uso HighWaterMarkChangeDetectionPolicy della _ts proprietà (timestamp) fornita da Azure Cosmos DB.

L'esempio seguente mostra una definizione di origine dati con un criterio di rilevamento delle modifiche:

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

Indicizzazione incrementale e query personalizzate

Se si usa una query personalizzata per recuperare i documenti, assicurarsi che la query ordini i risultati in base alla _ts colonna. In questo modo è possibile controllare periodicamente che Ricerca di intelligenza artificiale di Azure usa per fornire progressi incrementali in presenza di errori.

In alcuni casi, anche se la query contiene una ORDER BY [collection alias]._ts clausola , Ricerca di intelligenza artificiale di Azure potrebbe non dedurre che la query viene ordinata in base a _ts. È possibile indicare a Ricerca di intelligenza artificiale di Azure che i risultati vengono ordinati impostando la assumeOrderByHighWaterMarkColumn proprietà di configurazione.

Per specificare questo hint, creare o aggiornare la definizione dell'indicizzatore come indicato di seguito:

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

Indicizzazione di documenti eliminati

Quando si eliminano righe dalla raccolta, in genere le si elimina anche dall'indice di ricerca. Scopo dei criteri di rilevamento dell'eliminazione dei dati è quello di identificare in modo efficace gli elementi di dati eliminati. Attualmente, l'unico criterio supportato è il Soft Delete criterio (l'eliminazione è contrassegnata con un flag di ordinamento), specificato nella definizione dell'origine dati come indicato di seguito:

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

Se si usa una query personalizzata, assicurarsi che la proprietà a cui fa riferimento sia proiettata softDeleteColumnName dalla query.

Deve softDeleteColumnName essere un campo di primo livello nell'indice. L'uso di campi annidati all'interno di tipi di softDeleteColumnName dati complessi non è supportato.

L'esempio seguente crea un'origine dati con criteri di eliminazione temporanea:

POST https://[service name].search.windows.net/datasources?api-version=2023-11-01
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"
    }
}

Usare .NET

Per accedere ai dati tramite il protocollo API SQL, è possibile usare .NET SDK per automatizzare con gli indicizzatori. È consigliabile esaminare le sezioni precedenti dell'API REST per apprendere concetti, flussi di lavoro e requisiti. È quindi possibile fare riferimento alla documentazione di riferimento dell'API .NET seguente per implementare un indicizzatore JSON nel codice gestito:

Passaggi successivi

È ora possibile controllare come eseguire l'indicizzatore, monitorare lo stato o pianificare l'esecuzione dell'indicizzatore. Gli articoli seguenti si applicano agli indicizzatori che estraggono il contenuto da Azure Cosmos DB: