Indicizzare ed eseguire query sui vettori in Azure Cosmos DB for NoSQL in .NET.
SI APPLICA A: NoSQL
Ricerca vettoriale in Azure Cosmos DB for NoSQL è attualmente una funzionalità di anteprima. Per poterla usare, è necessario registrarsi per l'anteprima. Questo articolo illustra i passaggi seguenti:
- Registrazione per l'anteprima di Ricerca vettoriale in Azure Cosmos DB for NoSQL
- Configurazione del contenitore Azure Cosmos DB per la ricerca vettoriale
- Definizione dei criteri di incorporamento vettoriale
- Aggiunta di indici vettoriali ai criteri di indicizzazione dei contenitori
- Creazione di un contenitore con indici vettoriali e criteri di incorporamento vettoriale
- Esecuzione di una ricerca vettoriale sui dati archiviati.
- Questa guida illustra il processo di creazione di dati vettoriali, l'indicizzazione dei dati e quindi l'esecuzione di query sui dati in un contenitore.
Prerequisiti
- Un account Azure Cosmos DB per NoSQL già presente.
- Se non si ha un abbonamento ad Azure, prova gratuitamente Azure Cosmos DB per NoSQL.
- Se si ha già un abbonamento ad Azure, creare un nuovo account Azure Cosmos DB per NoSQL.
- La versione più recente dell'SDK di .NET per Azure Cosmos DB (3.41.0-preview.0)
Registrazione per l'anteprima
La ricerca vettoriale per Azure Cosmos DB for NoSQL richiede la registrazione della funzionalità di anteprima. Per effettuare la registrazione, seguire questa procedura:
Passare alla pagina della risorsa Azure Cosmos DB for NoSQL.
Selezionare il riquadro "Funzionalità" nella voce di menu "Impostazioni".
Selezionare "Ricerca vettoriale in Azure Cosmos DB for NoSQL".
Leggere la descrizione della funzionalità per confermare la registrazione nell'anteprima.
Selezionare "Abilita" per registrarsi all'anteprima.
Nota
La richiesta di registrazione verrà approvata automaticamente, ma potrebbero essere necessari alcuni minuti prima che diventi effettiva.
Informazioni sulla procedura necessaria per la ricerca vettoriale
La procedura seguente presuppone che sia in grado di configurare un account Cosmos DB NoSQL e di creare un database. La funzionalità di ricerca vettoriale non è attualmente supportata nei contenitori esistenti. È quindi necessario creare un nuovo contenitore e, durante il processo di creazione del contenitore, specificare i criteri di incorporamento vettoriale a livello di contenitore e i criteri di indicizzazione vettoriale.
Si prenda come esempio la creazione di un database per una libreria online in cui, per ogni libro, vengono archiviate le informazioni seguenti: Titolo, Autore, ISBN e Descrizione. Vengono inoltre definite due proprietà necessarie per poter contenere incorporamenti vettoriali. La prima è la proprietà "contentVector", contenente incorporamenti di testo generati dal contenuto di testo del libro (ad esempio, concatenando le proprietà "title" "author" "isbn" e "description" prima di creare l'incorporamento). La seconda è "coverImageVector", generata dalle immagini della copertina del libro.
- Creare e archiviare incorporamenti vettoriali per i campi in cui si desidera eseguire la ricerca vettoriale.
- Specificare i percorsi di incorporamento vettoriale nei criteri di incorporamento vettoriale.
- Includere eventuali indici vettoriali desiderati nei criteri di indicizzazione per il contenitore.
Nelle sezioni successive di questo articolo, si considererà 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]
}
Creazione di criteri di incorporamento vettoriale per il contenitore.
È ora necessario definire criteri vettoriali per il contenitore. 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. Questi criteri forniscono anche le informazioni necessarie ai criteri di indicizzazione vettoriale, se si sceglie di specificarli. Nei criteri vettoriali contenuti sono disponibili le informazioni seguenti:
- "path": percorso della proprietà contenente i vettori
- "datatype": tipo degli elementi del vettore (tipo predefinito: Float32)
- "dimensions": lunghezza di ogni vettore presente nel percorso (dimensione predefinita: 1536)
- "distanceFunction": metrica usata per calcolare la distanza/somiglianza (metrica predefinita: Coseno)
Riprendendo l'esempio con i dettagli dei libri, i criteri vettoriali potrebbero avere un aspetto simile a questo codice JSON di esempio qui di seguito:
Database db = await client.CreateDatabaseIfNotExistsAsync("vector-benchmarking");
List<Embedding> embeddings = new List<Embedding>()
{
new Embedding()
{
Path = "/coverImageVector",
DataType = VectorDataType.Float32,
DistanceFunction = DistanceFunction.Cosine,
Dimensions = 8,
},
new Embedding()
{
Path = "/contentVector",
DataType = VectorDataType.Float32,
DistanceFunction = DistanceFunction.Cosine,
Dimensions = 10,
}
};
Creazione di indici vettoriali nei criteri di indicizzazione
Dopo aver deciso i percorsi di incorporamento vettoriali, è necessario aggiungere gli indici vettoriali ai criteri di indicizzazione. Attualmente la funzionalità di ricerca vettoriale per Azure Cosmos DB for NoSQL è supportata solo nei nuovi contenitori e, pertanto, è necessario applicare i criteri vettoriali al momento della creazione del contenitore e non è possibile modificarli in un secondo momento. Per questo esempio, i criteri di indicizzazione saranno simile a:
Collection<Embedding> collection = new Collection<Embedding>(embeddings);
ContainerProperties properties = new ContainerProperties(id: "vector-container", partitionKeyPath: "/id")
{
VectorEmbeddingPolicy = new(collection),
IndexingPolicy = new IndexingPolicy()
{
VectorIndexes = new()
{
new VectorIndexPath()
{
Path = "/vector",
Type = VectorIndexType.QuantizedFlat,
}
}
},
};
properties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
properties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/vector/*" });
Importante
Percorso vettoriale aggiunto alla sezione "excludedPaths" dei criteri di indicizzazione per garantire prestazioni ottimizzate per l'inserimento. Se non si aggiunge il percorso vettoriale a "excludedPaths", l’addebito e la latenza delle RU risulteranno più elevati.
Importante
Attualmente la ricerca vettoriale in Azure Cosmos DB for NoSQL è supportata solo nei nuovi contenitori. Al momento della creazione del contenitore è necessario impostare sia i criteri vettoriali del contenitore sia eventuali criteri di indicizzazione vettoriale, poiché non potranno più essere modificati. Entrambi i tipi di criteri risulteranno modificabili in un miglioramento futuro della funzionalità di anteprima.
Esecuzione di una query di ricerca di somiglianza vettoriale
Dopo aver creato un contenitore con i criteri vettoriali desiderati e aver inserito i dati vettoriali nel contenitore, è possibile eseguire una ricerca vettoriale usando la funzione di sistema Vector Distance in una query. Si supponga di voler cercare libri di ricette in base alla descrizione. È prima necessario ottenere gli incorporamenti per il testo della query. In questo caso, potrebbe essere necessario generare incorporamenti per il testo di query "food recipe" (ricetta). Dopo aver ottenuto l'incorporamento per la query di ricerca, è possibile usarlo nella funzione VectorDistance nella query di ricerca vettoriale e ottenere tutti gli elementi simili alla query, come illustrato di seguito:
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 .NET:
float[] embedding = {1f,2f,3f,4f,5f,6f,7f,8f,9f,10f};
var queryDef = new QueryDefinition(
query: $"SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)"
).WithParameter("@embedding", embedding);
using FeedIterator<Object> feed = container.GetItemQueryIterator<Object>(
queryDefinition: queryDef
);
while (feed.HasMoreResults)
{
FeedResponse<Object> response = await feed.ReadNextAsync();
foreach ( Object item in response)
{
Console.WriteLine($"Found item:\t{item}");
}
}