Archivio vettoriale in Azure Cosmos DB per MongoDB vCore

SI APPLICA A: MongoDB vCore

Usare il database vettoriale integrato in Azure Cosmos DB per MongoDB vCore per connettere facilmente le applicazioni basate su intelligenza artificiale ai dati archiviati in Azure Cosmos DB. Questa integrazione può includere applicazioni create usando gli incorporamenti OpenAI di Azure. Il database vettoriale integrato in modo nativo consente di archiviare, indicizzare ed eseguire query su dati vettoriali altamente dimensionali archiviati direttamente in Azure Cosmos DB per MongoDB vCore, insieme ai dati originali da cui vengono creati i dati vettoriali. Elimina la necessità di trasferire i dati in archivi vettoriali alternativi e comporta costi aggiuntivi.

Che cos'è un archivio vettoriale?

Un archivio vettoriale o un database vettoriale è un database progettato per archiviare e gestire incorporamenti vettoriali, che sono rappresentazioni matematiche dei dati in uno spazio ad alta dimensione. In questo spazio, ogni dimensione corrisponde a una caratteristica dei dati e decine di migliaia di dimensioni possono essere usate per rappresentare dati sofisticati. La posizione di un vettore in questo spazio rappresenta le sue caratteristiche. Parole, frasi o interi documenti, immagini, audio e altri tipi di dati possono essere vettorizzati.

Come funziona un archivio vettoriale?

In un archivio vettoriale, gli algoritmi di ricerca vettoriale vengono usati per indicizzare ed eseguire query sugli incorporamenti. Alcuni algoritmi di ricerca vettoriale noti includono Gerarchica Navigable Small World (HNSW), File invertito (IVF), DiskANN e così via. La ricerca vettoriale è un metodo che consente di trovare elementi simili in base alle caratteristiche dei dati anziché in base alle corrispondenze esatte in un campo di proprietà. Questa tecnica è utile nelle applicazioni come la ricerca di testi simili o di immagini correlate, la creazione di elementi consigliati o anche il rilevamento di anomalie. Viene usato per eseguire query sui vettori di incorporamento (elenchi di numeri) dei dati creati usando un modello di Machine Learning usando un'API di incorporamento. Esempi di API di incorporamento sono gli incorporamenti OpenAI di Azure o Hugging Face in Azure. La ricerca vettoriale misura la distanza tra i vettori di dati e il vettore di query. I vettori di dati più vicini al vettore di query sono quelli che risultano più simili dal punto di vista semantico.

Nel database vettoriale integrato in Azure Cosmos DB per MongoDB vCore è possibile archiviare, indicizzare ed eseguire query insieme ai dati originali. Questo approccio elimina il costo aggiuntivo della replica dei dati in un database vettoriale puro separato. Inoltre, questa architettura mantiene insieme gli incorporamenti vettoriali e i dati originali, che facilitano meglio le operazioni di dati multi modale e consentono una maggiore coerenza, scalabilità e prestazioni dei dati.

Creare un indice vettoriale

Per eseguire la ricerca di similiarità vettoriale sulle proprietà vettoriali nei documenti, è necessario prima creare un indice vettoriale.

Creare un indice vettoriale con HNSW

È possibile creare indici (Gerarchica Navigable Small World) nei livelli del cluster M40 e versioni successive. Per creare l'indice HSNW, è necessario creare un indice vettoriale con il "kind" parametro impostato su "vector-hnsw" come segue il modello seguente:

{ 
    "createIndexes": "<collection_name>",
    "indexes": [
        {
            "name": "<index_name>",
            "key": {
                "<path_to_property>": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": <integer_value>, 
                "efConstruction": <integer_value>, 
                "similarity": "<string_value>", 
                "dimensions": <integer_value> 
            } 
        } 
    ] 
}
Campo Tipo Descrzione
index_name stringa Nome univoco dell'indice.
path_to_property string Percorso della proprietà che contiene il vettore. Questo percorso può essere una proprietà di primo livello o un percorso di notazione con punto per la proprietà. Se viene utilizzato un percorso di notazione con punto, tutti gli elementi non foglia non possono essere matrici. I vettori devono essere un number[] da indicizzare e restituire nei risultati della ricerca vettoriale.
kind string Tipo di indice vettoriale da creare. Le opzioni sono vector-ivf e vector-hnsw. Nota vector-ivf : è disponibile in tutti i livelli del cluster ed vector-hnsw è disponibile nei livelli del cluster M40 e versioni successive.
m integer Il numero massimo di connessioni per livello (16 per impostazione predefinita, il valore minimo è 2, il valore massimo è 100). Un valore m più alto è adatto per i set di dati con elevata dimensionalità e/o requisiti di elevata precisione.
efConstruction integer La dimensione dell'elenco di candidati dinamici per la costruzione del grafo (64 per impostazione predefinita, il valore minimo è 4, il valore massimo è 1000). Un valore efConstruction più alto comporterà una migliore qualità e una maggiore accuratezza dell'indice, ma aumenterà anche il tempo necessario per compilare l'indice. efConstruction deve essere almeno 2 * m
similarity string Metrica di somiglianza da usare con l'indice. Le opzioni possibili sono COS (distanza coseno), L2 (distanza euclidea) e IP (prodotto interno).
dimensions integer Numero di dimensioni per la somiglianza di vettore. Il numero massimo di dimensioni supportate è 2000.

Eseguire una ricerca vettoriale con HNSW

Per eseguire una ricerca vettoriale, utilizzare la $searchfase della pipeline di aggregazione per organizzare la query con l'operatore cosmosSearch.

{
    "$search": {
        "cosmosSearch": {
            "vector": <query_vector>,
            "path": "<path_to_property>",
            "k": <num_results_to_return>,
            "efSearch": <integer_value>
        },
    }
  }
}

Campo Tipo Descrizione
efSearch integer Dimensioni dell'elenco dei candidati dinamici per la ricerca (40 per impostazione predefinita). Un valore più alto fornisce un richiamo migliore a scapito della velocità.
k integer Numero di risultati da restituire. Deve essere minore o uguale a efSearch

Nota

La creazione di un indice HSNW con set di dati di grandi dimensioni può comportare l'esaurimento della memoria della risorsa vCore di Azure Cosmos DB per MongoDB oppure limitare le prestazioni di altre operazioni in esecuzione nel database. Se si verificano problemi di questo tipo, questi possono essere mitigati ridimensionando la risorsa a un livello cluster superiore o riducendo le dimensioni del set di dati.

Creare un indice vettoriale usando IVF

Per creare un indice vettoriale usando l'algoritmo IVF (Inverted File), usare il modello seguente createIndexes e impostare il "kind" parametro su "vector-ivf":

{
  "createIndexes": "<collection_name>",
  "indexes": [
    {
      "name": "<index_name>",
      "key": {
        "<path_to_property>": "cosmosSearch"
      },
      "cosmosSearchOptions": {
        "kind": "vector-ivf",
        "numLists": <integer_value>,
        "similarity": "<string_value>",
        "dimensions": <integer_value>
      }
    }
  ]
}
Campo Tipo Descrzione
index_name stringa Nome univoco dell'indice.
path_to_property string Percorso della proprietà che contiene il vettore. Questo percorso può essere una proprietà di primo livello o un percorso di notazione con punto per la proprietà. Se viene utilizzato un percorso di notazione con punto, tutti gli elementi non foglia non possono essere matrici. I vettori devono essere un number[] da indicizzare e restituire nei risultati della ricerca vettoriale.
kind string Tipo di indice vettoriale da creare. Le opzioni sono vector-ivf e vector-hnsw. Nota vector-ivf : è disponibile in tutti i livelli del cluster ed vector-hnsw è disponibile nei livelli del cluster M40 e versioni successive.
numLists integer Questo numero intero è il numero di cluster utilizzati dall'indice di file invertito (IVF) per raggruppare i dati di vettore. È consigliabile impostare numLists su documentCount/1000 per un massimo di 1 milione di documenti e su sqrt(documentCount) per più di 1 milione di documenti. L'uso di un valore numLists di 1 è simile all'esecuzione di una ricerca di forza bruta, con prestazioni limitate.
similarity string Metrica di somiglianza da usare con l'indice. Le opzioni possibili sono COS (distanza coseno), L2 (distanza euclidea) e IP (prodotto interno).
dimensions integer Numero di dimensioni per la somiglianza di vettore. Il numero massimo di dimensioni supportate è 2000.

Importante

Impostare correttamente il parametro numLists è importante per ottenere accuratezza e prestazioni ottimali. È consigliabile impostare numLists su documentCount/1000 per un massimo di 1 milione di documenti e su sqrt(documentCount) per più di 1 milione di documenti.

Man mano che aumenta il numero di elementi nel database, è necessario aumentare le dimensioni di numLists per ottenere prestazioni di latenza ottimali per la ricerca vettoriale.

Se si sta sperimentando un nuovo scenario o si sta creando una demo di piccole dimensioni, è possibile iniziare con numLists impostato su 1 per eseguire una ricerca di forza bruta su tutti i vettori. Questo dovrebbe fornire i risultati più accurati della ricerca vettoriale, tuttavia è necessario tenere presente che la velocità e la latenza di ricerca saranno lente. Dopo la configurazione iniziale, è necessario procedere e ottimizzare il parametro numLists usando le indicazioni illustrate in precedenza.

Eseguire una ricerca vettoriale con IVF

Per eseguire una ricerca vettoriale, usare la fase della pipeline di aggregazione $search in una query MongoDB. Per usare l'indice cosmosSearch, usare il nuovo operatore cosmosSearch.

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <query_vector>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

Per recuperare il punteggio di somiglianza (searchScore) insieme ai documenti trovati dalla ricerca vettoriale, utilizzare l'operatore $project per includere searchScore e rinominarlo come <custom_name_for_similarity_score> nei risultati. Il documento viene quindi proiettato anche come oggetto annidato. Tenere presente che il punteggio di somiglianza viene calcolato usando la metrica definita nell'indice vettoriale.

Importante

I vettori devono essere un number[] da indicizzare. L'utilizzo di tipi diversi, ad esempio double[], impedisce l'indicizzazione del documento. I documenti non indicizzati non verranno restituiti nei risultati di una ricerca vettoriale.

Esempio che usa un indice HNSW.

Gli esempi seguenti illustrano come indicizzare i vettori, aggiungere documenti con proprietà vettoriali, eseguire una ricerca vettoriale e recuperare la configurazione dell'indice.

use test;

db.createCollection("exampleCollection");

db.runCommand({ 
    "createIndexes": "exampleCollection",
    "indexes": [
        {
            "name": "VectorSearchIndex",
            "key": {
                "contentVector": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": 16, 
                "efConstruction": 64, 
                "similarity": "COS", 
                "dimensions": 3
            } 
        } 
    ] 
});

Questo comando crea un indice HNSW sulla contentVector proprietà nei documenti archiviati nell'insieme specificato, exampleCollection. La cosmosSearchOptions proprietà specifica i parametri per l'indice vettoriale HNSW. Se il documento contiene il vettore archiviato in una proprietà annidata, è possibile configurare questa proprietà usando un percorso di notazione con punto. Ad esempio, è possibile usare text.contentVector se contentVector è una sottoproprietà di text.

Aggiungere vettori al database

Per aggiungere vettori alla raccolta del database, è necessario creare innanzitutto gli incorporamenti usando il modello che si possiede, gli incorporamenti OpenAI di Azure o un'altra API (ad esempio Hugging Face in Azure). Nell'esempio riportato di seguito vengono aggiunti nuovi documenti tramite incorporamenti di esempio:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

Continuando con l'ultimo esempio, creare un altro vettore: queryVector. La ricerca vettoriale misura la distanza tra queryVector e i vettori nel percorso contentVector dei documenti. È possibile impostare il numero di risultati restituiti dalla ricerca configurando il parametro k, qui impostato su 2. È anche possibile impostare efSearch, ovvero un numero intero che controlla le dimensioni dell'elenco di vettori candidati. Un valore più alto può migliorare l'accuratezza, di conseguenza però la ricerca sarà più lenta. Si tratta di un parametro facoltativo con un valore predefinito pari a 40.

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    "$search": {
        "cosmosSearch": {
            "vector": "queryVector",
            "path": "contentVector",
            "k": 2,
            "efSearch": 40
        },
    }
  }
}
]);

In questo esempio viene eseguita una ricerca vettoriale usando queryVector come input tramite Mongo Shell. Il risultato della ricerca è un elenco di due elementi che sono più simili al vettore di query, ordinati in base al punteggio di somiglianza.

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

Ottenere definizioni di indice vettoriale

Per recuperare la definizione di indice vettoriale dalla raccolta, usare il comando listIndexes:

db.exampleCollection.getIndexes();

In questo esempio, vectorIndex viene restituito con tutti i parametri cosmosSearch usati per creare l'indice:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { contentVector: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-hnsw',
      m: 40,
      efConstruction: 64
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

Esempio di utilizzo di un indice IVF

Gli esempi seguenti illustrano come indicizzare i vettori, aggiungere documenti con proprietà vettoriali, eseguire una ricerca vettoriale e recuperare la configurazione dell'indice.

Creare un indice vettoriale

use test;

db.createCollection("exampleCollection");

db.runCommand({
  createIndexes: 'exampleCollection',
  indexes: [
    {
      name: 'vectorSearchIndex',
      key: {
        "vectorContent": "cosmosSearch"
      },
      cosmosSearchOptions: {
        kind: 'vector-ivf',
        numLists: 3,
        similarity: 'COS',
        dimensions: 3
      }
    }
  ]
});

Questo comando crea un indice vector-ivf rispetto alla proprietà vectorContent nei documenti archiviati nell'insieme specificato, come exampleCollection. La proprietà cosmosSearchOptions specifica i parametri per l'indice vettoriale IVF. Se il documento contiene il vettore archiviato in una proprietà annidata, è possibile configurare questa proprietà usando un percorso di notazione con punto. Ad esempio, è possibile usare text.vectorContent se vectorContent è una sottoproprietà di text.

Aggiungere vettori al database

Per aggiungere vettori alla raccolta del database, è necessario creare innanzitutto gli incorporamenti usando il modello che si possiede, gli incorporamenti OpenAI di Azure o un'altra API (ad esempio Hugging Face in Azure). Nell'esempio riportato di seguito vengono aggiunti nuovi documenti tramite incorporamenti di esempio:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

Eseguire una ricerca vettoriale

Per eseguire una ricerca vettoriale, usare la fase della pipeline di aggregazione $search in una query MongoDB. Per usare l'indice cosmosSearch, usare il nuovo operatore cosmosSearch.

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <vector_to_search>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

Per recuperare il punteggio di somiglianza (searchScore) insieme ai documenti trovati dalla ricerca vettoriale, utilizzare l'operatore $project per includere searchScore e rinominarlo come <custom_name_for_similarity_score> nei risultati. Il documento viene quindi proiettato anche come oggetto annidato. Tenere presente che il punteggio di somiglianza viene calcolato usando la metrica definita nell'indice vettoriale.

Continuando con l'ultimo esempio, creare un altro vettore: queryVector. La ricerca vettoriale misura la distanza tra queryVector e i vettori nel percorso vectorContent dei documenti. È possibile impostare il numero di risultati restituiti dalla ricerca configurando il parametro k, qui impostato su 2. È anche possibile impostare nProbes, ovvero un numero intero che controlla il numero di cluster nelle vicinanze che vengono esaminati in ogni ricerca. Un valore più alto può migliorare l'accuratezza, di conseguenza però la ricerca sarà più lenta. Si tratta di un parametro facoltativo con un valore predefinito pari a 1 e non può essere maggiore del valore numLists specificato nell'indice vettoriale.

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    $search: {
      "cosmosSearch": {
        "vector": queryVector,
        "path": "vectorContent",
        "k": 2
      },
    "returnStoredSource": true }},
  {
    "$project": { "similarityScore": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
]);

In questo esempio viene eseguita una ricerca vettoriale usando queryVector come input tramite Mongo Shell. Il risultato della ricerca è un elenco di due elementi che sono più simili al vettore di query, ordinati in base al punteggio di somiglianza.

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

Ottenere definizioni di indice vettoriale

Per recuperare la definizione di indice vettoriale dalla raccolta, usare il comando listIndexes:

db.exampleCollection.getIndexes();

In questo esempio, vectorIndex viene restituito con tutti i parametri cosmosSearch usati per creare l'indice:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { vectorContent: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-ivf',
      numLists: 3,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

Ricerca vettoriale filtrata (anteprima)

È ora possibile eseguire ricerche vettoriali con qualsiasi filtro di query supportato, ad $ltesempio , $gt$gte$lte$neq$in$eq, $nin, e .$regex Abilitare la funzionalità "ricerca di vettori di filtro" nella scheda "Funzionalità di anteprima" della sottoscrizione di Azure. Altre informazioni sulle funzionalità di anteprima sono disponibili qui.

In primo luogo, è necessario definire un indice per il filtro oltre a un indice vettoriale. Ad esempio, è possibile definire l'indice del filtro in una proprietà

db.runCommand({ 
     "createIndexes": "<collection_name",
    "indexes": [ {
        "key": { 
            "<property_to_filter>": 1 
               }, 
        "name": "<name_of_filter_index>" 
    }
    ] 
});

Successivamente, è possibile aggiungere il "filter" termine alla ricerca vettoriale, come illustrato di seguito. In questo esempio il filtro cerca documenti in cui la "title" proprietà non è nell'elenco di ["not in this text", "or this text"].


db.exampleCollection.aggregate([
  {
      '$search': {
          "cosmosSearch": {
              "vector": "<query_vector>",
              "path": <path_to_vector>,
              "k": num_results,
              "filter": {<property_to_filter>: {"$nin": ["not in this text", "or this text"]}}
          },
          "returnStoredSource": True }},
      {'$project': { 'similarityScore': { '$meta': 'searchScore' }, 'document' : '$$ROOT' }
}
]);

Importante

Durante l'anteprima, la ricerca di vettori filtrati potrebbe richiedere di modificare i parametri dell'indice vettoriale per ottenere un'accuratezza maggiore. Ad esempio, l'aumento mdi , efConstructiono efSearch quando si usa HNSW o numLists, o nProbes quando si usa IVF, può causare risultati migliori. È necessario testare la configurazione prima di usare per assicurarsi che i risultati siano soddisfacenti.

Usare gli strumenti di orchestrazione LLM

Usare come database vettoriale con kernel semantico

Usare il kernel semantico per orchestrare il recupero delle informazioni da Azure Cosmos DB per MongoDB vCore e LLM. Altre informazioni qui.

https://github.com/microsoft/semantic-kernel/tree/main/python/semantic_kernel/connectors/memory/azure_cosmosdb

Usare come database vettoriale con LangChain

Usare LangChain per orchestrare il recupero delle informazioni da Azure Cosmos DB per MongoDB vCore e LLM. Altre informazioni qui.

Usare come cache semantica con LangChain

Usare LangChain e Azure Cosmos DB per MongoDB (vCore) per orchestrare la memorizzazione nella cache semantica usando le risposte LLM recocrded in precedenza che consentono di risparmiare sui costi dell'API LLM e ridurre la latenza per le risposte. Scopri di più qui

Funzionalità e limitazioni

  • Metriche di distanza supportate: L2 (euclideo), prodotto interno e coseno.
  • Metodi di indicizzazione supportati: IVFFLAT (disponibilità generale) e HSNW (anteprima)
  • Indicizzazione di vettori con dimensioni fino a 2.000.
  • L'indicizzazione si applica a un solo vettore per percorso.
  • È possibile creare un solo indice per percorso vettoriale.

Riepilogo

Questa guida illustra come creare un indice vettoriale, aggiungere documenti con dati vettoriali, eseguire una ricerca di somiglianza e recuperare la definizione dell'indice. Usando il database vettoriale integrato, è possibile archiviare, indicizzare ed eseguire query sui dati vettoriali ad alta dimensione direttamente in Azure Cosmos DB per MongoDB vCore. Consente di sfruttare appieno il potenziale dei dati tramite incorporamenti vettoriali e consente di creare applicazioni più accurate, efficienti e potenti.

Passaggio successivo