Condividi tramite


Indicizzare ed eseguire query vettoriali in Azure Cosmos DB for NoSQL in Python

Questo articolo illustra come creare dati vettoriali, indicizzare i dati e quindi eseguire query sui dati in un contenitore.

Prima di usare l'indicizzazione e la ricerca di vettori, è necessario abilitare la ricerca vettoriale in Azure Cosmos DB per NoSQL. Dopo aver configurato il contenitore di Azure Cosmos DB per la ricerca vettoriale, si creano criteri di incorporamento vettoriali. Successivamente, si aggiungono indici vettoriali ai criteri di indicizzazione dei contenitori. Creare quindi un contenitore con indici vettoriali e criteri di incorporamento vettoriali. Infine, si esegue una ricerca vettoriale sui dati archiviati.

Prerequisiti

Abilitare la funzionalità

Per abilitare la ricerca vettoriale per Azure Cosmos DB per NoSQL, seguire questa procedura:

  1. Passare alla pagina della risorsa di Azure Cosmos DB for NoSQL.
  2. Nel riquadro sinistro, in Impostazioni, selezionare Funzionalità.
  3. Selezionare Ricerca vettoriale per l'API NoSQL.
  4. Leggere la descrizione della funzionalità per confermare che si vuole abilitarla.
  5. Selezionare Abilita per attivare la ricerca vettoriale in Azure Cosmos DB per NoSQL.

Suggerimento

In alternativa, usare l'interfaccia della riga di comando di Azure per aggiornare le funzionalità dell'account per supportare la ricerca vettoriale di Azure Cosmos DB per NoSQL.

az cosmosdb update \
     --resource-group <resource-group-name> \
     --name <account-name> \
     --capabilities EnableNoSQLVectorSearch

La richiesta di registrazione viene approvata automaticamente, ma potrebbero essere necessari 15 minuti.

I passaggi seguenti presuppongono che si sappia come configurare un account Azure Cosmos DB per NoSQL e creare un database. La funzionalità di ricerca vettoriale non è attualmente supportata nei contenitori esistenti. È necessario creare un nuovo contenitore. Quando si crea il contenitore, si specificano i criteri di incorporamento del vettore a livello di contenitore e i criteri di indicizzazione vettoriale.

Di seguito è riportato un esempio di come creare un database per un booktore basato su Internet. Si desidera archiviare le informazioni su titolo, autore, ISBN e descrizione per ogni libro. È anche necessario definire le due proprietà seguenti per contenere incorporamenti vettoriali:

  • La contentVector proprietà contiene incorporamenti di testo generati dal contenuto di testo del libro. Ad esempio, si concatenano le proprietà title, author, isbn e description prima di creare l'integrazione.
  • La coverImageVector proprietà viene generata dalle immagini della copertina del libro.

Per eseguire una ricerca vettoriale, è necessario:

  1. Creare e archiviare incorporamenti vettoriali per i campi in cui si desidera eseguire la ricerca vettoriale.
  2. Specificare i percorsi di incorporamento vettoriale nei criteri di incorporamento vettoriale.
  3. Includere gli indici vettoriali desiderati nei criteri di indicizzazione per il contenitore.

Per le sezioni successive di questo articolo, considerare la struttura seguente per gli elementi archiviati nel contenitore:

{
  "title": "book-title", 
  "author": "book-author", 
  "isbn": "book-isbn", 
  "description": "book-description", 
  "contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1], 
  "coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78] 
}

Creare un criterio di incorporamento vettoriale per il contenitore

È ora necessario definire un criterio per i vettori dei contenitori. Questi criteri forniscono le informazioni che verranno usate per istruire il motore di query di Azure Cosmos DB su come gestire le proprietà vettoriali nelle funzioni di sistema VectorDistance. Questo criterio fornisce anche le informazioni necessarie per i criteri di indicizzazione vettoriali, se si sceglie di specificarne uno.

Nei criteri vettoriali contenitore sono disponibili le informazioni seguenti:

Parametro Descrizione
path Percorso della proprietà contenente i vettori.
datatype Tipo degli elementi del vettore. Il valore predefinito è Float32.
dimensions Lunghezza di ogni vettore nel percorso. Il valore predefinito è 1536.
distanceFunction Metrica usata per calcolare distanza/somiglianza. Il valore predefinito è Cosine.

Per l'esempio con i dettagli del libro, i criteri vettoriali potrebbero essere simili all'esempio seguente:

vector_embedding_policy = { 
    "vectorEmbeddings": [ 
        { 
            "path": "/coverImageVector", 
            "dataType": "float32", 
            "distanceFunction": "dotproduct", 
            "dimensions": 8 
        }, 
        { 
            "path": "/contentVector", 
            "dataType": "float32", 
            "distanceFunction": "cosine", 
            "dimensions": 10 
        } 
    ]    
} 

Creare un indice vettoriale nei criteri di indicizzazione

Dopo aver deciso i percorsi di incorporamento dei vettori, è necessario aggiungere indici vettoriali ai criteri di indicizzazione. Il criterio di indicizzazione è simile all'esempio seguente:

indexing_policy = { 
    "includedPaths": [ 
        { 
            "path": "/*" 
        } 
    ], 
    "excludedPaths": [ 
        { 
            "path": "/\"_etag\"/?",
            "path": "/coverImageVector/*",
            "path": "/contentVector/*"
            
        } 
    ], 
    "vectorIndexes": [ 
        {"path": "/coverImageVector", 
         "type": "quantizedFlat" 
        }, 
        {"path": "/contentVector", 
         "type": "quantizedFlat" 
        } 
    ] 
} 

Importante

Il percorso vettoriale viene aggiunto alla excludedPaths sezione dei criteri di indicizzazione per garantire prestazioni ottimizzate per l'inserimento. Non aggiungere il percorso vettoriale a excludedPaths risulta in un costo unitario di richiesta maggiore e una latenza più elevata per gli inserimenti vettoriali.

Attualmente, la ricerca vettoriale in Azure Cosmos DB per NoSQL è supportata solo nei nuovi contenitori. È necessario impostare sia i criteri del vettore del contenitore che i criteri di indicizzazione dei vettori quando si crea il contenitore perché non è possibile modificarlo in un secondo momento.

Creare un contenitore con una politica vettoriale

Attualmente, la funzionalità di ricerca vettoriale per Azure Cosmos DB per NoSQL è supportata solo nei nuovi contenitori. Quando si crea il contenitore, si applicano i criteri vettoriali. Non è possibile modificare i criteri in un secondo momento.

try:     
    container = db.create_container_if_not_exists( 
                    id=CONTAINER_NAME, 
                    partition_key=PartitionKey(path='/id'), 
                    indexing_policy=indexing_policy, 
                    vector_embedding_policy=vector_embedding_policy) 
    print('Container with id \'{0}\' created'.format(id)) 

except exceptions.CosmosHttpResponseError: 
        raise 

Eseguire una query di ricerca di somiglianza vettoriale

Dopo aver creato un contenitore con i criteri vettoriali desiderati e inserire dati vettoriali nel contenitore, usare la funzione di sistema VectorDistance in una query per eseguire una ricerca vettoriale.

Si supponga di voler cercare libri sulle ricette alimentari esaminando la descrizione. Prima di tutto, è necessario ottenere gli embedding per il testo della query. In questo caso, potrebbe essere necessario generare incorporamenti per il testo food recipedella query . Dopo aver ottenuto l'incorporamento per la query di ricerca, è possibile usarlo nella funzione VectorDistance nella query di ricerca vettoriale per ottenere tutti gli elementi simili alla query:

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])   

Questa query recupera i titoli dei libri insieme ai punteggi di somiglianza rispetto alla tua query. Ecco un esempio in Python:

query_embedding = [1,2,3,4,5,6,7,8,9,10] 
# Query for items 
for item in container.query_items( 
            query='SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)', 
            parameters=[ 
                {"name": "@embedding", "value": query_embedding} 
            ], 
            enable_cross_partition_query=True): 
    print(json.dumps(item, indent=True))