Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ismerje meg, hogyan használhat vektorkeresést az Azure DocumentDB-ben a Java MongoDB-illesztőprogrammal a vektoradatok hatékony tárolásához és lekérdezéséhez.
Ez a rövid útmutató a fő vektorkeresési technikákat ismerteti egy Java-mintaalkalmazással a GitHubon.
Az alkalmazás egy szállodai mintaadatkészletet használ egy JSON-fájlban, amelyben előre kiszámított vektorok vannak a text-embedding-3-small modellből, de a vektorokat saját maga is létrehozhatja. A szálloda adatai közé tartoznak a szállodanevek, a helyek, a leírások és a vektoros beágyazások.
Prerequisites
Azure-előfizetés
- Ha nem rendelkezik Azure-előfizetéssel, hozzon létre egy ingyenes fiókot
Meglévő Azure DocumentDB-fürt
Ha nincs klasztere, hozzon létre egy új klasztert
A szerepköralapú hozzáférés-vezérlés (RBAC) engedélyezve van
Az ügyfél IP-címéhez való hozzáférés engedélyezésére konfigurált tűzfal
-
Egyéni tartomány konfigurálva
A szerepköralapú hozzáférés-vezérlés (RBAC) engedélyezve van
text-embedding-3-smallüzembe helyezett modell
Használja a Bash-környezetet az Azure Cloud Shellben. További információért lásd: Az Azure Cloud Shell használatának kezdő lépései.
Ha a CLI referencia parancsokat helyben szeretnéd futtatni, telepítsd az Azure CLI-t. Ha Windows vagy macOS rendszeren fut, fontolja meg az Azure CLI-t egy Docker-konténerben futtatni. További információkért lásd: Az Azure CLI használata Docker-konténerben.
Ha egy helyileg telepített verziót használ, jelentkezzen be az Azure CLI-be az az login parancs futtatásával. Az azonosítási folyamat befejezéséhez kövesse a terminálján megjelenő lépéseket. További bejelentkezési lehetőségekért lásd: Az Azure CLI használatával történő Azure-hitelesítést.
Amikor megjelenik a felszólítás, az első használatkor telepítse az Azure CLI bővítményt. További információ a bővítményekről: Bővítmények használata és kezelése az Azure CLI-vel.
Futtasd a az version parancsot, hogy megtudd a telepített verziót és függő könyvtárakat. A legújabb verzióra való frissítéshez futtassa a az upgrade parancsot.
Adatfájl létrehozása vektorokkal
Hozzon létre egy új adatkönyvtárat a hotels adatfájlhoz:
mkdir dataMásolja a
Hotels_Vector.jsonnyers adatfájlt vektorokkal adatakönyvtárba.
Java-projekt létrehozása
Hozzon létre egy új testvérkönyvtárat a projekthez az adatkönyvtárral megegyező szinten, és nyissa meg a Visual Studio Code-ban:
mkdir vector-search-quickstart mkdir vector-search-quickstart/src code vector-search-quickstartHozzon létre egy
pom.xmlfájlt a projekt gyökérkönyvtárában a következő tartalommal:<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>Az alkalmazás a következő Maven-függőségeket használja a
pom.xml:-
mongodb-driver-sync: Hivatalos MongoDB Java-illesztőprogram adatbázis-kapcsolathoz és műveletekhez -
azure-identity: Azure Identity-kódtár jelszó nélküli hitelesítéshez a Microsoft Entra-azonosítóval -
azure-ai-openai: Azure OpenAI-ügyfélkódtár AI-modellekkel való kommunikációhoz és vektoros beágyazások létrehozásához -
jackson-databind: JSON szerializálási és deszerializálási kódtár -
slf4j-nop: Művelet nélküli SLF4J-kötés a MongoDB-illesztőprogram naplózási kimenetének letiltásához
-
Hozzon létre egy
.envfájlt a projekt gyökerében környezeti változókhoz:# 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=50Cserélje le a
.envfájl helyőrzőit a saját adataival.-
AZURE_OPENAI_EMBEDDING_ENDPOINT: Az Azure OpenAI-erőforrásvégpont URL-címe. -
MONGO_CLUSTER_NAME: Az Azure DocumentDB-erőforrás neve.
-
Töltse be a környezeti változókat:
set -a && source .env && set +aA projektszerkezetnek így kell kinéznie:
data └── Hotels_Vector.json vector-search-quickstart ├── .env ├── pom.xml └── src
Kód hozzáadása vektorkereséshez
Hozzon létre egy DiskAnn.java fájlt a src könyvtárban, és illessze be a következő kódba:
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;
}
}
Ez a kód a következő feladatokat hajtja végre:
- Jelszó nélküli kapcsolatot hoz létre az Azure DocumentDB-vel a MongoDB OIDC mechanizmussal
DefaultAzureCredential - Azure OpenAI-ügyfél létrehozása beágyazások létrehozásához
- Elveti és újra létrehozza a gyűjteményt, majd betölti a JSON-fájlból származó szállodai adatokat kötegekben
- Szabványos indexeket és vektorindexeket hoz létre algoritmusspecifikus beállításokkal
- Beágyazást hoz létre egy minta lekérdezéshez, és egy összesítő keresési folyamatot futtat
- Az öt legjobb egyező hotelt nyomtatja ki hasonlósági pontszámmal
Autentikálj az Azure-hoz
Jelentkezzen be az Azure-ba az alkalmazás futtatása előtt, hogy biztonságosan hozzáférhessen az Azure-erőforrásokhoz.
Megjegyzés:
Győződjön meg arról, hogy a bejelentkezett felhasználói fiók rendelkezik a szükséges adatsík-szerepkörökkel mind az Azure DocumentDB-fiókon, mind az Azure OpenAI-erőforráson.
az login
A kód a helyi fejlesztői hitelesítést használja az Azure DocumentDB és az Azure OpenAI eléréséhez. Ha beállítja AZURE_TOKEN_CREDENTIALS=AzureCliCredential, ez a beállítás arra utasítja a függvényt, hogy determinisztikus módon használja az Azure CLI hitelesítő adatait a hitelesítéshez. A hitelesítés a DefaultAzureCredential-re a azure-identity-ből támaszkodik, hogy megtalálja az Azure-beli hitelesítő adatait a környezetben. További információ arról, hogyan lehet a Java-alkalmazásokat hitelesíteni az Azure szolgáltatásokhoz az Azure Identity könyvtár használatával.
Az alkalmazás létrehozása
Fordítsa le az alkalmazást
mvn clean compile
DiskANN (lemezalapú hozzávetőleges legközelebbi szomszéd) keresés elindítása:
mvn exec:java -Dexec.mainClass="com.azure.documentdb.samples.DiskAnn"
A DiskANN olyan nagy adathalmazokhoz van optimalizálva, amelyek nem férnek el a memóriában, hatékony lemezalapú tárolásra, valamint a sebesség és a pontosság megfelelő egyensúlyára.
A kimenet példája:
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
Adatok megtekintése és kezelése a Visual Studio Code-ban
Telepítse a Java DocumentDB bővítményét és bővítménycsomagját a Visual Studio Code-ban.
Csatlakozzon Azure DocumentDB-fiókjához a DocumentDB bővítmény használatával.
Az adatok és indexek megtekintése a Hotels adatbázisban.
Erőforrások tisztítása
Törölje az erőforráscsoportot, az Azure DocumentDB-fürtöt és az Azure OpenAI-erőforrást, ha már nincs rájuk szüksége a szükségtelen költségek elkerülése érdekében.