Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Erfahren Sie, wie Sie die Vektorsuche in Azure DocumentDB mit dem Java MongoDB-Treiber verwenden, um Vektordaten effizient zu speichern und abzufragen.
Diese Schnellstartanleitung bietet eine geführte Tour durch wichtige Vektorsuchtechniken mithilfe einer Java-Beispiel-App auf GitHub.
Die App verwendet ein Beispiel-Hotel-Dataset in einer JSON-Datei mit vorab berechneten Vektoren aus dem text-embedding-3-small Modell, aber Sie können die Vektoren auch selbst generieren. Die Hoteldaten umfassen Hotelnamen, Standorte, Beschreibungen und Vektoreinbettungen.
Voraussetzungen
Ein Azure-Abonnement
- Wenn Sie nicht über ein Azure-Abonnement verfügen, erstellen Sie ein kostenloses Konto
Ein vorhandener Azure DocumentDB-Cluster
Wenn Sie keinen Cluster haben, erstellen Sie einen neuen Cluster.
Rollenbasierte Zugriffssteuerung (Role Based Access Control, RBAC) aktiviert
Firewall für den Zugriff auf Ihre Client-IP-Adresse konfiguriert
-
Benutzerdefinierte Domäne konfiguriert
Rollenbasierte Zugriffssteuerung (Role Based Access Control, RBAC) aktiviert
text-embedding-3-smallbereitgestelltes Modell
Verwenden Sie die Bash-Umgebung in Azure Cloud Shell. Weitere Informationen finden Sie unter "Erste Schritte mit Azure Cloud Shell".
Wenn Sie CLI-Referenzbefehle lieber lokal ausführen möchten, installieren Sie die Azure CLI. Wenn Sie mit Windows oder macOS arbeiten, sollten Sie die Azure CLI in einem Docker-Container ausführen. Weitere Informationen finden Sie unter Ausführen der Azure CLI in einem Docker-Container.
Wenn Sie eine lokale Installation verwenden, melden Sie sich mithilfe des Befehls az login bei der Azure CLI an. Führen Sie die in Ihrem Terminal angezeigten Schritte aus, um den Authentifizierungsprozess abzuschließen. Weitere Anmeldeoptionen finden Sie unter Authentifizieren bei Azure mithilfe der Azure CLI.
Wenn Sie dazu aufgefordert werden, installieren Sie die Azure CLI-Erweiterung bei der ersten Verwendung. Weitere Informationen zu Erweiterungen finden Sie unter Verwenden und Verwalten von Erweiterungen mit der Azure CLI.
Führen Sie az version aus, um die installierte Version und die abhängigen Bibliotheken zu ermitteln. Führen Sie az upgrade aus, um auf die neueste Version zu aktualisieren.
Erstellen einer Datendatei mit Vektoren
Erstellen Sie ein neues Datenverzeichnis für die Hotelsdatendatei:
mkdir dataKopieren Sie die
Hotels_Vector.jsonRohdatendatei mit Vektoren in IhrdataVerzeichnis.
Erstellen eines Java-Projekts
Erstellen Sie ein neues gleichgeordnetes Verzeichnis für Ihr Projekt auf derselben Ebene wie das Datenverzeichnis, und öffnen Sie es in Visual Studio Code:
mkdir vector-search-quickstart mkdir vector-search-quickstart/src code vector-search-quickstartErstellen Sie eine
pom.xmlDatei im Projektstamm mit dem folgenden Inhalt:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.azure.documentdb.samples</groupId> <artifactId>vector-search-quickstart</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.release>21</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> <version>5.6.2</version> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-identity</artifactId> <version>1.18.1</version> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-ai-openai</artifactId> <version>1.0.0-beta.16</version> </dependency> <dependency> <groupId>tools.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>2.0.17</version> <scope>runtime</scope> </dependency> </dependencies> </project>Die App verwendet die folgenden Maven-Abhängigkeiten, die im
pom.xmlangegeben sind.-
mongodb-driver-sync: Offizieller MongoDB-Java-Treiber für Datenbankkonnektivität und -vorgänge -
azure-identity: Azure Identity-Bibliothek für kennwortlose Authentifizierung mit Microsoft Entra-ID -
azure-ai-openai: Azure OpenAI-Clientbibliothek für die Kommunikation mit KI-Modellen und Erstellen von Vektoreinbettungen -
jackson-databind: JSON-Serialisierungs- und Deserialisierungsbibliothek -
slf4j-nop: Kein Vorgang für SLF4J-Bindung, um die Protokollausgabe des MongoDB-Treibers zu unterdrücken
-
Erstellen Sie eine
.envDatei im Projektstamm für Umgebungsvariablen:# Identity for local developer authentication with Azure CLI AZURE_TOKEN_CREDENTIALS=AzureCliCredential # Azure OpenAI Embedding Settings AZURE_OPENAI_EMBEDDING_MODEL=text-embedding-3-small AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15 AZURE_OPENAI_EMBEDDING_ENDPOINT= EMBEDDING_SIZE_BATCH=16 # Azure DocumentDB configuration MONGO_CLUSTER_NAME= # Data file DATA_FILE_WITH_VECTORS=../data/Hotels_Vector.json EMBEDDED_FIELD=DescriptionVector EMBEDDING_DIMENSIONS=1536 LOAD_SIZE_BATCH=50Ersetzen Sie die Platzhalterwerte in der
.envDatei durch Ihre eigenen Informationen:-
AZURE_OPENAI_EMBEDDING_ENDPOINT: Ihre Azure OpenAI-Ressourcenendpunkt-URL. -
MONGO_CLUSTER_NAME: Ihr Azure DocumentDB-Ressourcenname.
-
Laden sie die Umgebungsvariablen:
set -a && source .env && set +aDie Projektstruktur sollte wie folgt aussehen:
data └── Hotels_Vector.json vector-search-quickstart ├── .env ├── pom.xml └── src
Hinzufügen von Code für die Vektorsuche
Erstellen Sie eine DiskAnn.java Datei im src Verzeichnis, und fügen Sie den folgenden Code ein:
package com.azure.documentdb.samples;
import com.azure.ai.openai.OpenAIClient;
import com.azure.ai.openai.OpenAIClientBuilder;
import com.azure.ai.openai.models.EmbeddingsOptions;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Indexes;
import org.bson.Document;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.json.JsonMapper;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Vector search sample using DiskANN index.
*/
public class DiskAnn {
private static final String SAMPLE_QUERY = "quintessential lodging near running trails, eateries, retail";
private static final String DATABASE_NAME = "Hotels";
private static final String COLLECTION_NAME = "hotels_diskann";
private static final String VECTOR_INDEX_NAME = "vectorIndex_diskann";
private final JsonMapper jsonMapper = JsonMapper.builder().build();
public static void main(String[] args) {
new DiskAnn().run();
System.exit(0);
}
public void run() {
try (var mongoClient = createMongoClient()) {
var openAIClient = createOpenAIClient();
var database = mongoClient.getDatabase(DATABASE_NAME);
var collection = database.getCollection(COLLECTION_NAME, Document.class);
// Drop and recreate collection
collection.drop();
database.createCollection(COLLECTION_NAME);
System.out.println("Created collection: " + COLLECTION_NAME);
// Load and insert data
var hotelData = loadHotelData();
insertDataInBatches(collection, hotelData);
// Create standard indexes
createStandardIndexes(collection);
// Create vector index
createVectorIndex(database);
// Perform vector search
var queryEmbedding = createEmbedding(openAIClient, SAMPLE_QUERY);
performVectorSearch(collection, queryEmbedding);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
private MongoClient createMongoClient() {
var clusterName = System.getenv("MONGO_CLUSTER_NAME");
var managedIdentityPrincipalId = System.getenv("AZURE_MANAGED_IDENTITY_PRINCIPAL_ID");
var azureCredential = new DefaultAzureCredentialBuilder().build();
MongoCredential.OidcCallback callback = (MongoCredential.OidcCallbackContext context) -> {
var token = azureCredential.getToken(
new com.azure.core.credential.TokenRequestContext()
.addScopes("https://ossrdbms-aad.database.windows.net/.default")
).block();
if (token == null) {
throw new RuntimeException("Failed to obtain Azure AD token");
}
return new MongoCredential.OidcCallbackResult(token.getToken());
};
var credential = MongoCredential.createOidcCredential(null)
.withMechanismProperty("OIDC_CALLBACK", callback);
var connectionString = new ConnectionString(
String.format("mongodb+srv://%s@%s.mongocluster.cosmos.azure.com/?authMechanism=MONGODB-OIDC&tls=true&retrywrites=false&maxIdleTimeMS=120000",
managedIdentityPrincipalId, clusterName)
);
var settings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.credential(credential)
.build();
return MongoClients.create(settings);
}
private OpenAIClient createOpenAIClient() {
var endpoint = System.getenv("AZURE_OPENAI_EMBEDDING_ENDPOINT");
var credential = new DefaultAzureCredentialBuilder().build();
return new OpenAIClientBuilder()
.endpoint(endpoint)
.credential(credential)
.buildClient();
}
private List<Map<String, Object>> loadHotelData() throws IOException {
var dataFile = System.getenv("DATA_FILE_WITH_VECTORS");
var filePath = Path.of(dataFile);
System.out.println("Reading JSON file from " + filePath.toAbsolutePath());
var jsonContent = Files.readString(filePath);
return jsonMapper.readValue(jsonContent, new TypeReference<List<Map<String, Object>>>() {});
}
private void insertDataInBatches(MongoCollection<Document> collection, List<Map<String, Object>> hotelData) {
var batchSizeStr = System.getenv("LOAD_SIZE_BATCH");
var batchSize = batchSizeStr != null ? Integer.parseInt(batchSizeStr) : 100;
var batches = partitionList(hotelData, batchSize);
System.out.println("Processing in batches of " + batchSize + "...");
for (int i = 0; i < batches.size(); i++) {
var batch = batches.get(i);
var documents = batch.stream()
.map(Document::new)
.toList();
collection.insertMany(documents);
System.out.println("Batch " + (i + 1) + " complete: " + documents.size() + " inserted");
}
}
private void createStandardIndexes(MongoCollection<Document> collection) {
collection.createIndex(Indexes.ascending("HotelId"));
collection.createIndex(Indexes.ascending("Category"));
collection.createIndex(Indexes.ascending("Description"));
collection.createIndex(Indexes.ascending("Description_fr"));
}
private void createVectorIndex(MongoDatabase database) {
var embeddedField = System.getenv("EMBEDDED_FIELD");
var dimensionsStr = System.getenv("EMBEDDING_DIMENSIONS");
var dimensions = dimensionsStr != null ? Integer.parseInt(dimensionsStr) : 1536;
var indexDefinition = new Document()
.append("createIndexes", COLLECTION_NAME)
.append("indexes", List.of(
new Document()
.append("name", VECTOR_INDEX_NAME)
.append("key", new Document(embeddedField, "cosmosSearch"))
.append("cosmosSearchOptions", new Document()
.append("kind", "vector-diskann")
.append("dimensions", dimensions)
.append("similarity", "COS")
.append("maxDegree", 20)
.append("lBuild", 10)
)
));
database.runCommand(indexDefinition);
System.out.println("Created vector index: " + VECTOR_INDEX_NAME);
}
private List<Double> createEmbedding(OpenAIClient openAIClient, String text) {
var model = System.getenv("AZURE_OPENAI_EMBEDDING_MODEL");
var options = new EmbeddingsOptions(List.of(text));
var response = openAIClient.getEmbeddings(model, options);
return response.getData().get(0).getEmbedding().stream()
.map(Float::doubleValue)
.toList();
}
private void performVectorSearch(MongoCollection<Document> collection, List<Double> queryEmbedding) {
var embeddedField = System.getenv("EMBEDDED_FIELD");
var searchStage = new Document("$search", new Document()
.append("cosmosSearch", new Document()
.append("vector", queryEmbedding)
.append("path", embeddedField)
.append("k", 5)
)
);
var projectStage = new Document("$project", new Document()
.append("score", new Document("$meta", "searchScore"))
.append("document", "$$ROOT")
);
var pipeline = List.of(searchStage, projectStage);
System.out.println("\nVector search results for: \"" + SAMPLE_QUERY + "\"");
AggregateIterable<Document> results = collection.aggregate(pipeline);
var rank = 1;
for (var result : results) {
var document = result.get("document", Document.class);
var hotelName = document.getString("HotelName");
var score = result.getDouble("score");
System.out.printf("%d. HotelName: %s, Score: %.4f%n", rank++, hotelName, score);
}
}
private static <T> List<List<T>> partitionList(List<T> list, int batchSize) {
var partitions = new ArrayList<List<T>>();
for (int i = 0; i < list.size(); i += batchSize) {
partitions.add(list.subList(i, Math.min(i + batchSize, list.size())));
}
return partitions;
}
}
Dieser Code führt die folgenden Aufgaben aus:
- Erstellt eine kennwortlose Verbindung zu Azure DocumentDB mittels
DefaultAzureCredentialund des MongoDB-OIDC-Mechanismus - Erstellt einen Azure OpenAI-Client zum Generieren von Einbettungen
- Legt die Sammlung ab und erstellt sie neu und lädt dann Hoteldaten aus der JSON-Datei in Batches.
- Erstellt Standardindizes und einen Vektorindex mit algorithmusspezifischen Optionen
- Generiert eine Einbettung für eine Beispielabfrage und führt eine Aggregationssuchpipeline aus.
- Druckt die fünf besten übereinstimmenden Hotels mit Ähnlichkeitsbewertungen.
Für Azure authentifizieren
Melden Sie sich bei Azure an, bevor Sie die Anwendung ausführen, damit sie sicher auf Azure-Ressourcen zugreifen kann.
Hinweis
Stellen Sie sicher, dass Ihre angemeldete Identität über die erforderlichen Rollen auf der Datenebene sowohl im Azure DocumentDB-Konto als auch in der Azure OpenAI-Ressource verfügt.
az login
Der Code verwendet Ihre lokale Entwicklerauthentifizierung für den Zugriff auf Azure DocumentDB und Azure OpenAI. Wenn Sie diese Einstellung festlegen AZURE_TOKEN_CREDENTIALS=AzureCliCredential, weist diese Einstellung die Funktion an, Azure CLI-Anmeldeinformationen für die Authentifizierung deterministisch zu verwenden. Die Authentifizierung basiert auf DefaultAzureCredential aus azure-identity , um Ihre Azure-Anmeldeinformationen in der Umgebung zu finden. Erfahren Sie mehr darüber, wie Sie Java-Apps mit Azure-Diensten mithilfe der Azure Identity-Bibliothek authentifizieren.
Erstellen der Anwendung
Kompilieren Sie die Anwendung:
mvn clean compile
Führen Sie die DiskANN-Suche (Datenträgerbasierte ungefähre nächste Nachbarsuche) aus:
mvn exec:java -Dexec.mainClass="com.azure.documentdb.samples.DiskAnn"
DiskANN ist für große Datensätze optimiert, die nicht in den Arbeitsspeicher passen, sondern auf effizienten, datenträgerbasierten Speicher angewiesen sind, um eine gute Balance zwischen Geschwindigkeit und Genauigkeit zu gewährleisten.
Beispielausgabe:
Created collection: hotels_diskann
Reading JSON file from /workspaces/documentdb-samples/ai/vector-search-java/../data/Hotels_Vector.json
Processing in batches of 50...
Batch 1 complete: 50 inserted
Created vector index: vectorIndex_diskann
Vector search results for: "quintessential lodging near running trails, eateries, retail"
1. HotelName: Royal Cottage Resort, Score: 0.4991
2. HotelName: Country Comfort Inn, Score: 0.4786
3. HotelName: Nordick's Valley Motel, Score: 0.4635
4. HotelName: Economy Universe Motel, Score: 0.4462
5. HotelName: Roach Motel, Score: 0.4389
Anzeigen und Verwalten von Daten in Visual Studio Code
Installieren Sie die DocumentDB-Erweiterung und das Erweiterungspaket für Java in Visual Studio Code.
Stellen Sie mithilfe der DocumentDB-Erweiterung eine Verbindung mit Ihrem Azure DocumentDB-Konto her.
Zeigen Sie die Daten und Indizes der Datenbank "Hotels" an.
Bereinigen von Ressourcen
Löschen Sie die Ressourcengruppe, den Azure DocumentDB-Cluster und die Azure OpenAI-Ressource, wenn Sie sie nicht mehr benötigen, um unnötige Kosten zu vermeiden.