Index- und Abfragevektoren in Azure Cosmos DB for NoSQL in Java
Damit Sie die Vektorindizierung und -suche verwenden können, müssen Sie das Feature zunächst aktivieren. In diesem Artikel werden die folgenden Schritte behandelt:
- Aktivieren der Vektorsuche in Azure Cosmos DB for NoSQL
- Einrichten des Azure Cosmos DB-Containers für die Vektorsuche
- Richtlinie zum Erstellen von Vektoreinbettung
- Hinzufügen von Vektorindizes zur Containerindizierungsrichtlinie
- Erstellen eines Containers mit Vektorindizes und Vektoreinbettungsrichtlinie
- Durchführen einer Vektorsuche für die gespeicherten Daten
Dieser Leitfaden führt Sie durch den Prozess zum Erstellen und Indizieren von Vektordaten sowie zum anschließenden Abfragen dieser Daten in einem Container.
Voraussetzungen
- Ein vorhandenes Azure Cosmos DB for NoSQL-Konto.
- Wenn Sie kein Azure-Abonnement besitzen, testen Sie Azure Cosmos DB for NoSQL kostenlos.
- Wenn Sie über ein Azure-Abonnement verfügen, erstellen Sie einen neuen Azure Cosmos DB for NoSQL-Cluster.
- Die neuste Version des Java-SDK von Azure Cosmos DB.
Die Funktion aktivieren
Für die Vektorsuche für Azure Cosmos DB for NoSQL muss das entsprechende Feature aktiviert werden. Führen Sie die folgenden Schritte aus, um sich zu registrieren:
- Navigieren Sie zu Ihrer Azure Cosmos DB for NoSQL-Ressourcenseite.
- Wählen Sie den Bereich "Features" unter dem Menüelement "Einstellungen" aus.
- Wählen Sie „Vektorsuche in Azure Cosmos DB for NoSQL“ aus.
- Lesen Sie die Beschreibung des Features, und bestätigen Sie danach, dass Sie es aktivieren möchten.
- Wählen Sie „Aktivieren“ aus, um die Vektorsuche in Azure Cosmos DB for NoSQL zu aktivieren.
Tipp
Alternativ können Sie die Azure CLI verwenden, um die Funktionen Ihres Kontos zu aktualisieren und die NoSQL-Vektorsuche zu unterstützen.
az cosmosdb update \
--resource-group <resource-group-name> \
--name <account-name> \
--capabilities EnableNoSQLVectorSearch
Hinweis
Die Registrierungsanforderung wird automatisch genehmigt, es kann jedoch 15 Minuten dauern, bis sie wirksam wird.
Grundlegendes zu den Schritten, die bei der Vektorsuche erforderlich sind
Bei den folgenden Schritten wird davon ausgegangen, dass Sie wissen, wie Sie ein Cosmos DB NoSQL-Konto einrichten und eine Datenbank erstellen. Das Vektorsuchfeature wird derzeit für die vorhandenen Container nicht unterstützt. Daher müssen Sie einen neuen Container erstellen und die Vektor-Vektoreinbettungsrichtlinie und die Vektorindizierungsrichtlinie zum Zeitpunkt der Containererstellung angeben.
Sehen wir uns ein Beispiel für das Erstellen einer Datenbank für eine internetbasierte Buchhandlung an, und Sie speichern Titel, Autor, ISBN und Beschreibung für jedes Buch. Außerdem definieren wir zwei Eigenschaften, die Vektoreinbettungen enthalten sollen. Die erste ist die Eigenschaft "contentVector", die Texteinbettungen enthält, die aus dem Textinhalt des Buchs generiert werden (z. B. Verketten der Eigenschaften "title" "author" "isbn" und "description" vor dem Erstellen des Einbettens). Die zweite ist "coverImageVector", die aus Bildern des Bucheinbands generiert wird.
- Erstellen und speichern Sie Vektoreinbettungen für die Felder, für die Sie die Vektorsuche ausführen möchten.
- Geben Sie die Pfade zum Einbetten von Vektoren in die Vektoreinbettungsrichtlinie an.
- Fügen Sie alle gewünschten Vektorindizes in die Indizierungsrichtlinie für den Container ein.
Für nachfolgende Abschnitte dieses Artikels betrachten wir die folgende Struktur für die in unserem Container gespeicherten Elemente:
{
"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]
}
Erstellen Sie zunächst das Objekt CosmosContainerProperties
.
CosmosContainerProperties collectionDefinition = new CosmosContainerProperties(UUID.randomUUID().toString(), "Partition_Key_Def");
Erstellen einer Vektoreinbettungsrichtlinie für Ihren Container
Als Nächstes müssen Sie eine Containervektorrichtlinie definieren. Diese Richtlinie enthält Informationen, die verwendet werden, um das Azure Cosmos DB-Abfragemodul darüber zu informieren, wie Vektoreigenschaften in den VectorDistance-Systemfunktionen behandelt werden. Dies informiert auch die Vektorindizierungsrichtlinie über die erforderlichen Informationen, wenn Sie eine angeben möchten. Die folgenden Informationen sind in der enthaltenen Vektorrichtlinie enthalten:
- "path": Der Eigenschaftspfad, der Vektoren enthält
- "datatype": Der Typ der Elemente des Vektors (Standard Float32)
- "dimensions": Die Länge jedes Vektors im Pfad (Standard 1536)
- "distanceFunction": Die Metrik, die zum Berechnen der Entfernung/Ähnlichkeit verwendet wird (Standardkosinus)
Für unser Beispiel mit Buchdetails kann die Vektorrichtlinie wie das Beispiel JSON aussehen:
// 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);
Erstellen eines Vektorindexes in der Indizierungsrichtlinie
Sobald die Vektoreinbettungspfade festgelegt wurden, müssen Vektorindizes der Indizierungsrichtlinie hinzugefügt werden. Derzeit wird das Vektorsuchfeature für Azure Cosmos DB for NoSQL nur für neue Container unterstützt, sodass Sie die Vektorrichtlinie während des Zeitpunkts der Containererstellung anwenden müssen und sie später nicht geändert werden kann. In diesem Beispiel würde die Indizierungsrichtlinie etwa wie folgt aussehen:
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);
Erstellen Sie schließlich den Container mit der Containerindexrichtlinie und der Vektorindexrichtlinie.
database.createContainer(collectionDefinition).block();
Wichtig
Dieser Vektorpfad wurde dem Abschnitt „excludedPaths“ der Indizierungsrichtlinie hinzugefügt, um eine optimierte Leistung für das Einfügen sicherzustellen. Wenn der Vektorpfad nicht zu „excludedPaths“ hinzugefügt wird, führt dies zu einer höheren RU-Belastung und Latenz für Vektoreinfügungen.
Ausführen einer Suchabfrage zur Vektorähnlichkeit
Nachdem Sie einen Container mit der gewünschten Vektorrichtlinie erstellt und Vektordaten in den Container eingefügt haben, können Sie eine Vektorsuche mithilfe der Systemfunktion Vektordistanz in einer Abfrage durchführen. Angenommen, Sie möchten nach Büchern über Kochrezepte suchen, indem Sie sich die Beschreibung ansehen. Sie müssen dann zuerst die Einbettungen für Ihren Abfragetext abrufen. In diesem Fall möchten Sie möglicherweise Einbettungen für den Abfragetext "Lebensmittelrezept" generieren. Sobald Sie die Einbettung für Ihre Suchabfrage haben, können Sie sie in der VectorDistance-Funktion in der Vektorsuchabfrage verwenden und alle Elemente abrufen, die Ihrer Abfrage ähnlich sind, wie hier gezeigt:
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])
Diese Abfrage ruft die Buchtitel zusammen mit Ähnlichkeitsbewertungen in Bezug auf Ihre Abfrage ab. Hier ist ein Beispiel 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()));
}