Condividi tramite


Indicizzare ed eseguire query sui vettori in Azure Cosmos DB for NoSQL in Java

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. Vai alla pagina della risorsa Azure Cosmos DB per 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'incorporamento.
  • 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] 
} 

Prima di tutto, creare l'oggetto CosmosContainerProperties.

CosmosContainerProperties collectionDefinition = new CosmosContainerProperties(UUID.randomUUID().toString(), "Partition_Key_Def");

Creare un criterio di incorporamento vettoriale per il contenitore

Ora è necessario definire una politica del vettore di container. Questo criterio fornisce informazioni che informano il motore di query di Azure Cosmos DB su come gestire le proprietà vettoriali nelle funzioni di VectorDistance sistema. Questo criterio fornisce anche le informazioni necessarie per i criteri di indicizzazione vettoriali, se si sceglie di specificarne uno.

Le informazioni seguenti sono incluse nella politica del vettore del contenitore.

Parametro Description
path Percorso della proprietà che contiene 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 la distanza/similarità. Il valore predefinito è Cosine.

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

// Creating vector embedding policy
CosmosVectorEmbeddingPolicy cosmosVectorEmbeddingPolicy = new CosmosVectorEmbeddingPolicy();

CosmosVectorEmbedding embedding1 = new CosmosVectorEmbedding();
embedding1.setPath("/coverImageVector");
embedding1.setDataType(CosmosVectorDataType.FLOAT32);
embedding1.setDimensions(8L);
embedding1.setDistanceFunction(CosmosVectorDistanceFunction.COSINE);

CosmosVectorEmbedding embedding2 = new CosmosVectorEmbedding();
embedding2.setPath("/contentVector");
embedding2.setDataType(CosmosVectorDataType.FLOAT32);
embedding2.setDimensions(10L);
embedding2.setDistanceFunction(CosmosVectorDistanceFunction.DOT_PRODUCT);

cosmosVectorEmbeddingPolicy.setCosmosVectorEmbeddings(Arrays.asList(embedding1, embedding2, embedding3));

collectionDefinition.setVectorEmbeddingPolicy(cosmosVectorEmbeddingPolicy);

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. 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. Il criterio di indicizzazione è simile all'esempio seguente:

IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);
ExcludedPath excludedPath1 = new ExcludedPath("/coverImageVector/*");
ExcludedPath excludedPath2 = new ExcludedPath("/contentVector/*");
indexingPolicy.setExcludedPaths(ImmutableList.of(excludedPath1, excludedPath2));

IncludedPath includedPath1 = new IncludedPath("/*");
indexingPolicy.setIncludedPaths(Collections.singletonList(includedPath1));

// Creating vector indexes
CosmosVectorIndexSpec cosmosVectorIndexSpec1 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec1.setPath("/coverImageVector");
cosmosVectorIndexSpec1.setType(CosmosVectorIndexType.QUANTIZED_FLAT.toString());

CosmosVectorIndexSpec cosmosVectorIndexSpec2 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec2.setPath("/contentVector");
cosmosVectorIndexSpec2.setType(CosmosVectorIndexType.DISK_ANN.toString());

indexingPolicy.setVectorIndexes(Arrays.asList(cosmosVectorIndexSpec1, cosmosVectorIndexSpec2, cosmosVectorIndexSpec3));

collectionDefinition.setIndexingPolicy(indexingPolicy);

È necessario infine creare il contenitore con i criteri di indicizzazione del contenitore e i criteri di indicizzazione vettoriale.

database.createContainer(collectionDefinition).block();

Importante

Il percorso vettoriale viene aggiunto alla excludedPaths sezione dei criteri di indicizzazione per garantire prestazioni ottimizzate per l'inserimento. Non aggiungendo il percorso vettoriale a excludedPaths si ottiene un addebito di unità richiesta più elevato e una latenza più elevata per gli inserimenti vettoriali.

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 necessario ottenere gli incorporamenti per il testo della query. In questo caso, potrebbe essere necessario generare incorporamenti per il testo food recipedella query . Dopo aver ottenuto l'embedding per la tua query di ricerca, puoi usarlo nella funzione VectorDistance nella query di ricerca vettoriale per ottenere tutti gli elementi simili alla tua 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 e i relativi punteggi di somiglianza rispetto alla query. Ecco un esempio in Java:

float[] embedding = new float[10];
for (int i = 0; i < 10; i++) {
    array[i] = i + 1;
}
ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
  paramList.add(new SqlParameter("@embedding", embedding));
  SqlQuerySpec querySpec = new SqlQuerySpec("SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore  FROM c ORDER BY VectorDistance(c.contentVector,@embedding)", paramList);
  CosmosPagedIterable<Family> filteredFamilies = container.queryItems(querySpec, new CosmosQueryRequestOptions(), Family.class);

  if (filteredFamilies.iterator().hasNext()) {
      Family family = filteredFamilies.iterator().next();
      logger.info(String.format("First query result: Family with (/id, partition key) = (%s,%s)",family.getId(),family.getLastName()));
  }