Hızlı Başlangıç: Azure Cosmos DB'da Java ile vektör araması

Java istemci kitaplığıyla Azure Cosmos DB vektör araması kullanın. Vektör verilerini uygulamalarınızda verimli bir şekilde depolayın ve sorgulayın.

Bu hızlı başlangıçta, text-embedding-3-small modelindeki vektörlerle birlikte bir JSON dosyasında örnek bir otel veri kümesi kullanılmaktadır. Veri kümesi otel adlarını, konumlarını, açıklamalarını ve vektör eklemelerini içerir.

GitHub üzerinde kaynak sağlama ile örnek kodu bulun.

Prerequisites

Vektörlerle veri dosyası oluşturma

  1. Oteller veri dosyası için yeni bir veri dizini oluşturun:

    mkdir data
    
  2. vektörler içeren ham veri dosyasınıdata dizininize indirin.

    curl -o data/HotelsData_toCosmosDB_Vector.json https://raw.githubusercontent.com/Azure-Samples/cosmos-db-vector-samples/refs/heads/main/data/HotelsData_toCosmosDB_Vector.json
    

Java projesi oluşturma

  1. Projeniz için veri diziniyle aynı düzeyde yeni bir eşdüzey dizin oluşturun ve bunu Visual Studio Code'da açın:

    mkdir vector-search-quickstart
    cd vector-search-quickstart
    code .
    
  2. Maven yapılandırmasıyla proje kökünde bir pom.xml dosya oluşturun:

    <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.example.cosmos.samples</groupId>
        <artifactId>nosql-vector-search-sample</artifactId>
        <version>1.0.0</version>
        <name>Azure Cosmos DB NoSQL Vector Search - Java</name>
    
        <properties>
            <maven.compiler.release>21</maven.compiler.release>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!-- Azure Cosmos DB SDK (NoSQL API) -->
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-cosmos</artifactId>
                <version>4.69.0</version>
            </dependency>
    
            <!-- Azure Identity (DefaultAzureCredential) -->
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-identity</artifactId>
                <version>1.18.1</version>
            </dependency>
    
            <!-- Azure OpenAI (embeddings) -->
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-ai-openai</artifactId>
                <version>1.0.0-beta.16</version>
            </dependency>
    
            <!-- Jackson (JSON serialization) -->
            <dependency>
                <groupId>tools.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>3.0.3</version>
            </dependency>
    
            <!-- Suppress noisy SDK logging -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-nop</artifactId>
                <version>2.0.17</version>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>3.5.0</version>
                    <configuration>
                        <mainClass>com.example.cosmos.vectorsearch.VectorSearch</mainClass>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    Önemli bağımlılıklar:

    • azure-identity - parolasız (yönetilen kimlik) bağlantılar için Azure kimlik doğrulama kitaplığı
    • azure-cosmos - veritabanı işlemleri için Azure Cosmos DB istemci kitaplığı
    • azure-ai-openai - gömüler oluşturmak için Azure OpenAI SDK'sı
    • slf4j-nop - Çalışma zamanında gürültülü SDK günlüğünü bastırır
  3. Kaynak dizin yapısını oluşturun:

    mkdir -p src/main/java/com/example/cosmos/vectorsearch
    
  4. Ortam değişkenleri için proje kökünde bir .env dosya oluşturun:

    # Azure OpenAI Embedding Settings
    AZURE_OPENAI_EMBEDDING_MODEL=text-embedding-3-small
    AZURE_OPENAI_EMBEDDING_API_VERSION=2024-08-01-preview
    AZURE_OPENAI_EMBEDDING_ENDPOINT=
    
    # Cosmos DB configuration
    AZURE_COSMOSDB_ENDPOINT=
    
    # Data file
    DATA_FILE_WITH_VECTORS=../data/HotelsData_toCosmosDB_Vector.json
    FIELD_TO_EMBED=Description
    EMBEDDED_FIELD=DescriptionVector
    EMBEDDING_DIMENSIONS=1536
    
    # Vector search algorithm: diskann or quantizedflat
    VECTOR_ALGORITHM=diskann
    

    Dosyadaki .env yer tutucu değerlerini kendi bilgilerinizle değiştirin:

    • AZURE_OPENAI_EMBEDDING_ENDPOINT: Azure OpenAI kaynak uç noktası URL'niz
    • AZURE_COSMOSDB_ENDPOINT: Azure Cosmos DB uç nokta URL'niz

    Note

    Java örneği, ortam değişkenlerini okumak için System.getenv() kullanır. Bu değişkenleri kabuk oturumunuzda dışa aktarmanız gerekir veya bunları ayarlamak için azd env get-values kullanabilirsiniz. Dosya .env bir başvuru şablonu görevi görür; uygulama tarafından otomatik olarak yüklenmez.

Belge şemasını anlama

Uygulamayı oluşturmadan önce vektörlerin Azure Cosmos DB belgelerinde nasıl depolandığını anlayın. Her otel belgesinde aşağıdakiler bulunur:

  • Standart alanlar: HotelId, HotelName, Description, Category, vb.
  • Vektör alanı: DescriptionVector - Otel açıklamasının anlamsal anlamını temsil eden 1536 kayan noktalı sayı dizisi

Otel belgesi yapısının basitleştirilmiş bir örneği aşağıda verilmiştir:

{
  "HotelId": "1",
  "HotelName": "Stay-Kay City Hotel",
  "Description": "This classic hotel is fully-refurbished...",
  "Rating": 3.6,
  "DescriptionVector": [
    -0.04886505,
    -0.02030743,
    0.01763356,
    ...
    // 1536 dimensions total
  ]
}

Eklemeleri depolamayla ilgili önemli noktalar:

  • Vektör dizileri belgelerinizde standart JSON dizileri olarak depolanır
  • Vektör ilkesi yolu (/DescriptionVector), veri türünü (float32), boyutları (1536) ve uzaklık işlevini (kosinüs) tanımlar
  • Dizin oluşturma ilkesi , verimli benzerlik araması için vektör alanında bir vektör dizini oluşturur
  • Ekleme performansını iyileştirmek için vektör alanı standart dizin oluşturmanın dışında tutulmalıdır

Bu ilkeler, bu örnek projenin uzaklık ölçümleri için Bicep şablonlarında tanımlanır. Vektör ilkeleri ve dizin oluşturma hakkında daha fazla bilgi için bkz. Azure Cosmos DB'de vektör araması.

src/main/java/com/example/cosmos/vectorsearch dizininde iki Java kaynak dosyası oluşturun:

touch src/main/java/com/example/cosmos/vectorsearch/VectorSearch.java
touch src/main/java/com/example/cosmos/vectorsearch/Utils.java

Aşağıdaki kodu dosyaya yapıştırın VectorSearch.java .

package com.example.cosmos.vectorsearch;

import com.azure.ai.openai.OpenAIClient;
import com.azure.ai.openai.models.EmbeddingItem;
import com.azure.ai.openai.models.EmbeddingsOptions;
import com.azure.cosmos.CosmosClient;
import com.azure.cosmos.CosmosContainer;
import com.azure.cosmos.models.CosmosQueryRequestOptions;
import com.azure.cosmos.models.SqlParameter;
import com.azure.cosmos.models.SqlQuerySpec;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Azure Cosmos DB NoSQL vector search sample — Java port of nosql-vector-search-typescript.
 *
 * Demonstrates:
 * - Passwordless authentication with DefaultAzureCredential
 * - Bulk insert of hotel data with pre-computed embeddings
 * - Vector similarity search using VectorDistance() SQL function
 * - DiskANN and QuantizedFlat algorithm selection via environment variable
 */
public final class VectorSearch {

    private static final String SAMPLE_QUERY =
            "quintessential lodging near running trails, eateries, retail";

    private static final Set<String> VALID_ALGORITHMS = Set.of("diskann", "quantizedflat");

    private static final Map<String, String> ALGORITHM_CONTAINERS = Map.of(
            "diskann", "hotels_diskann",
            "quantizedflat", "hotels_quantizedflat"
    );

    private static final Map<String, String> ALGORITHM_DISPLAY = Map.of(
            "diskann", "DiskANN",
            "quantizedflat", "QuantizedFlat"
    );

    public static void main(String[] args) {
        try {
            new VectorSearch().run();
        } catch (Exception e) {
            System.err.println("App failed: " + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
        System.exit(0);
    }

    private void run() throws Exception {
        // ── Configuration ───────────────────────────────────────────────
        var algorithm = Utils.envOrDefault("VECTOR_ALGORITHM", "diskann").trim().toLowerCase();
        var dbName = Utils.envOrDefault("AZURE_COSMOSDB_DATABASENAME", "Hotels");
        var dataFile = Utils.requireEnv("DATA_FILE_WITH_VECTORS");
        var embeddedField = Utils.requireEnv("EMBEDDED_FIELD");
        var deployment = Utils.requireEnv("AZURE_OPENAI_EMBEDDING_MODEL");
        var distanceFunction = Utils.envOrDefault("VECTOR_DISTANCE_FUNCTION", "cosine");

        if (!VALID_ALGORITHMS.contains(algorithm)) {
            throw new IllegalArgumentException(
                    "Invalid algorithm '" + algorithm + "'. Must be one of: " +
                    String.join(", ", VALID_ALGORITHMS));
        }

        var containerName = ALGORITHM_CONTAINERS.get(algorithm);
        var algorithmDisplay = ALGORITHM_DISPLAY.get(algorithm);

        // ── Clients ─────────────────────────────────────────────────────
        OpenAIClient aiClient = Utils.createOpenAIClient();
        CosmosClient dbClient = Utils.createCosmosClient();

        try {
            var database = dbClient.getDatabase(dbName);
            System.out.println("Connected to database: " + dbName);

            CosmosContainer container = database.getContainer(containerName);
            System.out.println("Connected to container: " + containerName);
            System.out.println("\n[Algorithm] Vector Search Algorithm: " + algorithmDisplay);
            System.out.println("[Distance]  Distance Function: " + distanceFunction);

            // Verify container exists
            container.read();

            // ── Load & Insert Data ──────────────────────────────────────
            var dataPath = Path.of(dataFile);
            var data = Utils.readJsonFile(dataPath);
            Utils.insertData(container, data);

            // ── Generate Query Embedding ────────────────────────────────
            var embeddingOptions = new EmbeddingsOptions(List.of(SAMPLE_QUERY));
            var embeddingResult = aiClient.getEmbeddings(deployment, embeddingOptions);

            List<Float> embedding = embeddingResult.getData().get(0).getEmbedding();

            // Convert Float list to List<Double> for Cosmos DB parameter binding
            var embeddingDoubles = new ArrayList<Double>(embedding.size());
            for (var f : embedding) {
                embeddingDoubles.add(f.doubleValue());
            }

            // ── Build & Execute Vector Search Query ─────────────────────
            var safeField = Utils.validateFieldName(embeddedField);
            var queryText = "SELECT TOP 5 c.HotelName, c.Description, c.Rating, " +
                    "VectorDistance(c." + safeField + ", @embedding) AS SimilarityScore " +
                    "FROM c " +
                    "ORDER BY VectorDistance(c." + safeField + ", @embedding)";

            System.out.println("\n--- Executing Vector Search Query ---");
            System.out.println("Query: " + queryText);
            System.out.println("Parameters: @embedding (vector with " + embeddingDoubles.size() + " dimensions)");
            System.out.println("--------------------------------------\n");

            var sqlQuery = new SqlQuerySpec(
                    queryText,
                    List.of(new SqlParameter("@embedding", embeddingDoubles))
            );

            var queryOptions = new CosmosQueryRequestOptions();

            @SuppressWarnings("unchecked")
            var resultPages = container.queryItems(sqlQuery, queryOptions, Map.class);

            var results = new ArrayList<Map<String, Object>>();
            var requestCharge = 0.0;

            for (var page : resultPages.iterableByPage()) {
                requestCharge += page.getRequestCharge();
                for (var item : page.getResults()) {
                    @SuppressWarnings("unchecked")
                    var typedItem = (Map<String, Object>) item;
                    results.add(typedItem);
                }
            }

            Utils.printSearchResults(results, requestCharge);

        } finally {
            dbClient.close();
        }
    }
}

Bu kod:

  • Çevre değişkeninden, ya bir DiskANN ya da bir quantizedFlat vektör algoritması yapılandırır.
  • Azure OpenAI ve Azure Cosmos DB'ye parolasız kimlik doğrulaması kullanarak bağlanır.
  • JSON dosyasından önceden vektörleştirilmiş otel verilerini yükler.
  • Verileri uygun kapsayıcıya ekler.
  • Doğal dil sorgusu (quintessential lodging near running trails, eateries, retail) için ekleme oluşturur.
  • Benzerlik puanına göre sıralanan en benzer 5 oteli almak için bir VectorDistance SQL sorgusu yürütür.
  • Eksik istemciler, geçersiz algoritma seçimi ve mevcut olmayan kapsayıcılar/veritabanları için hataları işler.

Kodu anlama: Azure OpenAI ile eklemeler oluşturma

Kod, sorgu metni için eklemeler oluşturur:

EmbeddingsOptions options = new EmbeddingsOptions(
    List.of(queryText) // Array of description strings to embed
);
Embeddings embeddings = openAIClient.getEmbeddings(model, options);
List<Float> queryVector = embeddings.getData().get(0).getEmbedding();

Bu Azure OpenAI SDK çağrısı, "koşu patikalarının yakınında özgün bir konaklama" gibi metni anlamını kavrayarak 1536 boyutlu bir vektöre dönüştürür. Ekleme oluşturma hakkında daha fazla ayrıntı için bkz. Azure OpenAI ekleme belgeleri.

Kodu anlama: Azure Cosmos DB'de vektörleri depolama

Vektör dizilerine sahip tüm belgeler, executeBulkOperations içinde Utils.insertData() yöntemi kullanılarak ölçekli olarak eklenir. Her belge, her belgenin bölüm anahtarı değeri kullanılarak PartitionKeyBuilder ile toplu oluşturma işlemiyle eşleştirilir. Yardımcı program, eklenen, atlanan ve başarısız olan sayılarla birlikte toplam RU tüketimini izler.

Bu, önceden oluşturulmuş DescriptionVector dizilerini içeren otel belgelerini kapsayıcıya ekler. Tüm belge verilerini güvenli bir şekilde aktarabilirsiniz, ve bağlamda istemci kütüphanesi toplu işleme ve yeniden denemeleri sizin için işleyebilir.

Kod, VectorDistance işlevi kullanılarak bir vektör araması gerçekleştirir.

String queryText = String.format(
    "SELECT TOP 5 c.HotelName, c.Description, c.Rating, " +
    "VectorDistance(c.%s, @embedding) AS SimilarityScore " +
    "FROM c ORDER BY VectorDistance(c.%s, @embedding)",
    embeddedField, embeddedField
);

SqlQuerySpec querySpec = new SqlQuerySpec(queryText,
    new SqlParameter("@embedding", queryVector));

CosmosPagedIterable<ObjectNode> results = container.queryItems(
    querySpec, new CosmosQueryRequestOptions(), ObjectNode.class);

Bu kod, sorgunun ekleme vektörünü (@embedding) her belgenin depolanan vektör alanıylaDescriptionVector ( ) karşılaştırmak için VectorDistance işlevini kullanan, adı ve benzerlik puanı en az benzer olan en iyi 5 oteli sıralanmış olarak döndüren parametreli bir SQL sorgusu oluşturur. Sorgu gömüsü, enjeksiyonu önlemek amacıyla bir parametre olarak geçirilir ve önceki Azure OpenAI gömü çağrılarından gelir.

Bu sorgu ne döndürür:

  • Vektör uzaklığı temelinde en benzer 5 otel
  • Otel özellikleri: HotelName, Description, Rating
  • SimilarityScore: Her otelin sorgunuza ne kadar benzer olduğunu gösteren sayısal değer
  • En benzerden en az benzere sıralanmış sonuçlar

İşlev hakkında VectorDistance daha fazla bilgi için VectorDistance belgelerine bakın.

Yardımcı program işlevleri oluşturma

Aşağıdaki kodu içine Utils.javayapıştırın:

package com.example.cosmos.vectorsearch;

import com.azure.ai.openai.OpenAIClientBuilder;
import com.azure.ai.openai.OpenAIClient;
import com.azure.cosmos.CosmosClient;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.CosmosContainer;
import com.azure.cosmos.models.CosmosBulkOperations;
import com.azure.cosmos.models.CosmosItemOperation;
import com.azure.cosmos.models.PartitionKey;
import com.azure.cosmos.models.PartitionKeyBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;

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;

/**
 * Shared utilities for Azure Cosmos DB NoSQL vector search sample.
 * Provides authentication, bulk insert, field validation, and result formatting.
 */
public final class Utils {

    private static final JsonMapper JSON_MAPPER = JsonMapper.builder().build();

    private Utils() {
        // utility class
    }

    // ── Authentication ──────────────────────────────────────────────────

    /**
     * Create an Azure OpenAI client using DefaultAzureCredential (passwordless).
     */
    public static OpenAIClient createOpenAIClient() {
        var endpoint = requireEnv("AZURE_OPENAI_EMBEDDING_ENDPOINT");
        var credential = new DefaultAzureCredentialBuilder().build();
        return new OpenAIClientBuilder()
                .endpoint(endpoint)
                .credential(credential)
                .buildClient();
    }

    /**
     * Create a Cosmos DB client using DefaultAzureCredential (passwordless).
     */
    public static CosmosClient createCosmosClient() {
        var endpoint = requireEnv("AZURE_COSMOSDB_ENDPOINT");
        var credential = new DefaultAzureCredentialBuilder().build();
        return new CosmosClientBuilder()
                .endpoint(endpoint)
                .credential(credential)
                .buildClient();
    }

    // ── Data Loading ────────────────────────────────────────────────────

    /**
     * Read a JSON array file and return its contents as a list of maps.
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String, Object>> readJsonFile(Path filePath) throws IOException {
        System.out.println("Reading JSON file from " + filePath);
        var bytes = Files.readAllBytes(filePath);
        return JSON_MAPPER.readValue(bytes, List.class);
    }

    // ── Bulk Insert ─────────────────────────────────────────────────────

    /**
     * Insert documents into a Cosmos DB container using bulk operations.
     * Skips insert if the container already contains data.
     *
     * @return summary with counts and RU charge
     */
    public static BulkInsertResult insertData(CosmosContainer container,
                                               List<Map<String, Object>> data) {
        // Check existing document count
        var existingCount = getDocumentCount(container);
        if (existingCount > 0) {
            System.out.println("Container already has " + existingCount + " documents. Skipping insert.");
            return new BulkInsertResult(0, 0, 0, (int) existingCount, 0.0);
        }

        System.out.println("Inserting " + data.size() + " items using bulk operations...");

        // Build bulk create operations
        var operations = new ArrayList<CosmosItemOperation>();
        for (var item : data) {
            // Cosmos DB requires an "id" field — map HotelId to id
            var doc = new java.util.HashMap<>(item);
            var hotelId = String.valueOf(doc.get("HotelId"));
            doc.put("id", hotelId);
            operations.add(CosmosBulkOperations.getCreateItemOperation(doc,
                new PartitionKeyBuilder().add(hotelId).build()));
        }

        var inserted = 0;
        var failed = 0;
        var skipped = 0;
        var totalRUs = 0.0;

        var startTime = System.currentTimeMillis();
        System.out.println("Starting bulk insert (" + operations.size() + " items)...");

        var responses = container.executeBulkOperations(operations);
        for (var response : responses) {
            var statusCode = response.getResponse().getStatusCode();
            totalRUs += response.getResponse().getRequestCharge();

            if (statusCode >= 200 && statusCode < 300) {
                inserted++;
            } else if (statusCode == 409) {
                skipped++;
            } else {
                failed++;
            }
        }

        var durationSec = (System.currentTimeMillis() - startTime) / 1000.0;
        System.out.printf("Bulk insert completed in %.2fs%n", durationSec);
        System.out.printf("%nInsert Request Charge: %.2f RUs%n%n", totalRUs);

        return new BulkInsertResult(data.size(), inserted, failed, skipped, totalRUs);
    }

    private static long getDocumentCount(CosmosContainer container) {
        var result = container.queryItems(
                "SELECT VALUE COUNT(1) FROM c",
                new com.azure.cosmos.models.CosmosQueryRequestOptions(),
                Long.class
        );
        for (var count : result) {
            return count;
        }
        return 0;
    }

    // ── Field Name Validation ───────────────────────────────────────────

    /**
     * Validates a field name to prevent NoSQL injection when building queries
     * with string interpolation.
     *
     * @param fieldName the field name to validate
     * @return the validated field name
     * @throws IllegalArgumentException if the field name contains unsafe characters
     */
    public static String validateFieldName(String fieldName) {
        if (!fieldName.matches("^[A-Za-z_][A-Za-z0-9_]*$")) {
            throw new IllegalArgumentException(
                    "Invalid field name: \"" + fieldName + "\". " +
                    "Field names must start with a letter or underscore " +
                    "and contain only letters, numbers, and underscores.");
        }
        return fieldName;
    }

    // ── Output Formatting ───────────────────────────────────────────────

    /**
     * Print search results in a consistent tabular format.
     */
    public static void printSearchResults(List<Map<String, Object>> results, double requestCharge) {
        System.out.println("\n--- Search Results ---");

        if (results == null || results.isEmpty()) {
            System.out.println("No results found.");
            return;
        }

        for (var i = 0; i < results.size(); i++) {
            var r = results.get(i);
            var name = r.get("HotelName");
            var score = r.get("SimilarityScore");
            System.out.printf("%d. %s, Score: %.4f%n", i + 1, name, ((Number) score).doubleValue());
        }

        System.out.printf("%nVector Search Request Charge: %.2f RUs%n%n", requestCharge);
    }

    // ── Environment Helpers ─────────────────────────────────────────────

    public static String requireEnv(String key) {
        var value = System.getenv(key);
        if (value == null || value.isBlank()) {
            throw new IllegalStateException("Required environment variable not set: " + key);
        }
        return value;
    }

    public static String envOrDefault(String key, String defaultValue) {
        var value = System.getenv(key);
        return (value != null && !value.isBlank()) ? value : defaultValue;
    }

    // ── Result Record ───────────────────────────────────────────────────

    public record BulkInsertResult(int total, int inserted, int failed, int skipped, double requestCharge) {}
}

Bu yardımcı program sınıfı şu temel işlevleri sağlar:

  • createOpenAIClient / createCosmosClient: Azure OpenAI ve Azure Cosmos DB için parolasız kimlik doğrulama ile DefaultAzureCredential kullanarak istemciler oluşturun. Her iki kaynakta da RBAC'yi etkinleştirin ve Azure CLI'da oturum açın
  • insertData: Toplu işlemleri kullanarak verileri toplu olarak bir Azure Cosmos DB kapsayıcısına ekler ve eklenen, atlanan ve başarısız sayıları ve toplam RU tüketimini izler
  • printSearchResults: Puan ve otel adı dahil olmak üzere bir vektör aramasının sonuçlarını yazdırır
  • validateFieldName: Ekleme işlemini önlemek için verilerde bir alan adının bulunduğunu doğrular

Azure CLI ile kimlik doğrulaması

Uygulamanın Azure kaynaklarına güvenli bir şekilde erişebilmesi için uygulamayı çalıştırmadan önce Azure CLI'da oturum açın.

az login

Kod, yerel geliştirici kimlik doğrulamanızı kullanarak createOpenAIClient'den Azure Cosmos DB ve Azure OpenAI'ye createCosmosClient ve Utils.java ile erişir. Bu işlevler, DefaultAzureCredential ve azure-identity'den faydalanır ve sıralı bir kimlik bilgisi sağlayıcısı zincirini izleyerek, yerel geliştirme için Azure CLI kimlik bilgilerine çözümler. Azure Kimlik kitaplığını kullanarak Azure hizmetlerinde Java uygulamalarının kimliğini doğrulama hakkında daha fazla bilgi edinin.

Uygulamayı derleme ve çalıştırma

Maven ile uygulamayı derleyin ve çalıştırın:

Linux/macOS:

VECTOR_ALGORITHM=diskann mvn compile exec:java

Windows:

set VECTOR_ALGORITHM=diskann && mvn compile exec:java

Uygulamanın günlük ve çıktıları şunları gösterir:

  • Veri ekleme durumu
  • Vektör dizini oluşturma
  • Otel adları ve benzerlik puanları ile arama sonuçları
Connected to database: Hotels
Connected to container: hotels_diskann

📊 Vector Search Algorithm: DiskANN
📏 Distance Function: cosine
Reading JSON file from ../data/HotelsData_toCosmosDB_Vector.json
Inserting 50 items using bulk operations...
Starting bulk insert (50 items)...
Bulk insert completed in 3.41s

Insert Request Charge: 6805.25 RUs


--- Executing Vector Search Query ---
Query: SELECT TOP 5 c.HotelName, c.Description, c.Rating, VectorDistance(c.DescriptionVector, @embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.DescriptionVector, @embedding)
Parameters: @embedding (vector with 1536 dimensions)
--------------------------------------


--- Search Results ---
1. Royal Cottage Resort, Score: 0.4991
2. Country Comfort Inn, Score: 0.4786
3. Nordick's Valley Motel, Score: 0.4635
4. Economy Universe Motel, Score: 0.4461
5. Roach Motel, Score: 0.4388

Vector Search Request Charge: 5.33 RUs

Mesafe ölçümleri

Azure Cosmos DB, vektör benzerliği için üç uzaklık işlevini destekler:

Distance Fonksiyonu Puan Aralığı Yorumlama En Uygun
Kosünüs (varsayılan) 0,0 - 1,0 Daha yüksek puanlar (1,0'a yakın) daha fazla benzerlik gösterir Genel metin benzerliği, Azure OpenAI eklemeleri (bu hızlı başlangıçta kullanılır)
Öklid (L2) 0,0 ile ∞ Düşük = daha benzer Uzamsal veriler, büyüklük önemli olduğunda
NoktaLı Ürün -∞'den +∞'ye Daha yüksek = daha benzer Vektör büyüklükleri normalleştirildiğinde

Uzaklık işlevi, kapsayıcı oluşturulurken vektör ekleme ilkesinde ayarlanır. Bu, örnek depodaki altyapıda sağlanır. Kapsayıcı tanımının bir parçası olarak tanımlanır.

{
    name: 'hotels_diskann'
    partitionKeyPaths: [
        '/HotelId'
    ]
    indexingPolicy: {
        indexingMode: 'consistent'
        automatic: true
        includedPaths: [
        {
            path: '/*'
        }
        ]
        excludedPaths: [
        {
            path: '/_etag/?'
        }
        {
            path: '/DescriptionVector/*'
        }
        ]
        vectorIndexes: [
        {
            path: '/DescriptionVector'
            type: 'diskANN'
        }
        ]
    }
    vectorEmbeddingPolicy: {
        vectorEmbeddings: [
        {
            path: '/DescriptionVector'
            dataType: 'float32'
            dimensions: 1536
            distanceFunction: 'cosine'
        }
        ]
    }
}

Bu Bicep kodu, otel belgelerini vektör arama özellikleriyle depolamak için Azure Cosmos DB kapsayıcı yapılandırmasını tanımlar.

Mülkiyet Description
partitionKeyPaths Belgeleri HotelId kullanarak dağıtılmış depolama için böler.
indexingPolicy Yazma performansını iyileştirmek için sistem alanı /* ve _etag dizisi dışında tüm belge özelliklerinde DescriptionVector otomatik dizin oluşturma yapılandırır. Bunun yerine özel vectorIndexes bir yapılandırma kullandıklarından vektör alanlarının standart dizin oluşturması gerekmez.
vectorIndexes Verimli benzerlik aramaları için '/DescriptionVector' yolunda bir DiskANN veya quantizedFlat dizini oluşturur.
vectorEmbeddingPolicy Vektör alanının özelliklerini tanımlar: 1536 boyutlu float32 veri türü (model çıkışıyla text-embedding-3-small eşleşen) ve sorgular sırasında vektörler arasındaki benzerliği ölçmek için mesafe işlevi olarak kosinüs kullanılır.

Benzerlik puanlarını yorumlama

Kosinüs benzerliği kullanan örnek çıktıda:

  • 0.4991 (Royal Cottage Resort) - En yüksek benzerlik, "koşu parkurlarına yakın konaklama, yemek mekanları, perakende" için en iyi eşleşme
  • 0.4388 (Roach Motel) - Daha düşük benzerlik, hala ilgili ama daha az eşleştirme
  • 1,0'a yakın puanlar daha güçlü semantik benzerliği gösterir
  • 0'a yakın puanlar çok az benzerlik gösteriyor

Important

  • Mutlak puan değerleri ekleme modelinize ve verilerinize bağlıdır
  • Mutlak eşikler yerine göreli derecelendirmeye odaklanma
  • Azure OpenAI eklemeleri kosinüs benzerliğiyle en iyi sonucu sağlar

Uzaklık işlevleri hakkında ayrıntılı bilgi için bkz. Uzaklık işlevleri nelerdir?

Visual Studio Code'da verileri görüntüleme ve yönetme

  1. Azure Cosmos DB hesabınıza bağlanmak için Visual Studio Code'da Cosmos DB uzantısını seçin.

  2. Hotels veritabanındaki verileri ve dizinleri görüntüleyin.

    Oteller veritabanı öğeleri ve bir JSON belge düzenleyicisi ile Azure Cosmos DB uzantısını gösteren Visual Studio Code'un ekran görüntüsü.

Kaynakları temizle

NoSQL hesabı için API'ye artık ihtiyacınız kalmadığında ilgili kaynak grubunu silebilirsiniz.

  1. Azure portalında daha önce oluşturduğunuz kaynak grubuna gidin.

    Tip

    Bu hızlı başlangıç kılavuzunda ad olarak msdocs-cosmos-quickstart-rg önermiştik.

  2. Kaynak grubunu sil seçeneğini seçin.

    Bir kaynak grubunun gezinti çubuğundaki Kaynak grubunu sil seçeneğinin ekran görüntüsü.

  3. Silmek istediğinizden emin misiniz iletişim kutusunda kaynak grubunun adını girin ve Sil'i seçin.

    Kaynak grubunun silme onay sayfasının ekran görüntüsü.