Index- und Abfragevektoren in Azure Cosmos DB for NoSQL in Java
GILT FÜR: NoSQL
Die Vektorsuche in Azure Cosmos DB for NoSQL ist derzeit ein Vorschaufeature. Sie müssen sich vor der Verwendung für die Vorschau registrieren. In diesem Artikel werden die folgenden Schritte behandelt:
- Registrieren für die Vorschau 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.
Registrieren für die Vorschau
Für die Vektorsuche für Azure Cosmos DB for NoSQL ist eine Vorschau-Featureregistrierung erforderlich. 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 für "Vektorsuche in Azure Cosmos DB for NoSQL" aus.
Lesen Sie die Beschreibung des Features, um zu bestätigen, dass Sie sich in der Vorschau registrieren möchten.
Wählen Sie "Aktivieren" aus, um sich bei der Vorschau zu registrieren.
Hinweis
Die Registrierungsanforderung wird automatisch genehmigt, es kann jedoch mehrere 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.
Wichtig
Derzeit wird die Vektorsuche in Azure Cosmos DB for NoSQL nur für neue Container unterstützt. Sie müssen sowohl die Containervektorrichtlinie als auch jede Vektorindizierungsrichtlinie während des Zeitpunkts der Containererstellung festlegen, da sie später nicht geändert werden kann. Beide Richtlinien können in einer zukünftigen Verbesserung des Previewfeatures geändert werden.
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()));
}