Schnellstart: Vektorsuche

In dieser Schnellstartanleitung verwenden Sie die Azure KI-Suche-Clientbibliothek für .NET zum Erstellen, Laden und Abfragen eines vectorindex. Die .NET-Clientbibliothek bietet eine Abstraktion über die REST-APIs für Indexvorgänge.

In Azure KI-Suche verfügt ein Vektorindex über ein Indexschema, das Vektor- und Nichtvektorfelder definiert, eine Vektorsuchkonfiguration für Algorithmen, die den Einbettungsraum erstellen, sowie Einstellungen für Vektorfelddefinitionen, die zur Abfragezeit ausgewertet werden. Indizes – Erstellen oder Aktualisieren (REST-API) erstellt den Vektorindex.

Tipp

Voraussetzungen

  • Ein Azure Konto mit einem aktiven Abonnement. Erstellen Sie kostenlos ein Konto.

  • Ein Azure KI-Suche-Dienst. Sie können die Kostenlose Ebene für die meisten dieser Schnellstartanleitungen verwenden, aber wir empfehlen Basic oder höher für größere Datendateien.

  • .NET 8 oder höher.

  • Git um das Beispiel-Repository zu klonen.

  • Die Azure CLI für die schlüssellose Authentifizierung mit Microsoft Entra ID.

Konfigurieren des Zugriffs

Bevor Sie beginnen, stellen Sie sicher, dass Sie über Berechtigungen für den Zugriff auf Inhalte und Vorgänge in Azure KI-Suche verfügen. In dieser Schnellstartanleitung werden Microsoft Entra ID für die Authentifizierung und den rollenbasierten Zugriff für die Autorisierung verwendet. Sie müssen ein Besitzer oder Benutzerzugriffsadministrator sein, um Rollen zuzuweisen. Wenn Rollen nicht machbar sind, verwenden Sie stattdessen die schlüsselbasierte Authentifizierung .

So konfigurieren Sie den empfohlenen rollenbasierten Zugriff:

  1. Aktivieren Sie den rollenbasierten Zugriff für Ihren Suchdienst.

  2. Weisen Sie Ihrem Benutzerkonto die folgenden Rollen zu.

    • Suchdienstmitwirkender

    • Datenbeitragender für den Suchindex

    • Suchindexdatenleser

Endpunkt abrufen

Jeder Azure KI-Suche Dienst verfügt über einen endpoint, einer eindeutigen URL, die den Netzwerkzugriff auf den Dienst identifiziert und bereitstellt. In einem späteren Abschnitt geben Sie diesen Endpunkt an, um programmgesteuert eine Verbindung mit Ihrem Suchdienst herzustellen.

So rufen Sie den Endpunkt ab:

  1. Wechseln Sie zum Suchdienst im Azure-Portal.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich den Endpunkt, der wie https://my-service.search.windows.net folgt aussehen wird.

Einrichten der Umgebung

  1. Verwenden Sie Git, um das Beispiel-Repository zu klonen.

    git clone https://github.com/Azure-Samples/azure-search-dotnet-samples
    
  2. Navigieren Sie zum Schnellstartordner.

    cd azure-search-dotnet-samples/quickstart-vector-search
    
  3. In VectorSearchCreatePopulateIndex/appsettings.json ersetzen Sie den Platzhalterwert durch die URL, die Sie im Get-Endpunkt in Endpoint abgerufen haben.

  4. Wiederholen Sie den vorherigen Schritt für VectorSearchExamples/appsettings.json.

  5. Melden Sie sich für die schlüssellose Authentifizierung mit Microsoft Entra ID bei Ihrem Azure-Konto an. Wenn Sie über mehrere Abonnements verfügen, wählen Sie das Abonnement aus, das Ihren Azure KI-Suche Dienst enthält.

    az login
    

Ausführen des Codes

  1. Führen Sie das erste Projekt aus, um den Index zu erstellen und aufzufüllen.

    cd VectorSearchCreatePopulateIndex
    dotnet run
    
  2. Entfernen Sie in VectorSearchExamples/Program.cs die Kommentarzeichen bei den Abfragemethoden, die Sie ausführen möchten.

  3. Führen Sie das zweite Projekt aus, um diese Abfragen für den Index auszuführen.

    cd ..\VectorSearchExamples
    dotnet run
    

Ausgabe

Die Ausgabe des ersten Projekts umfasst die Bestätigung der Indexerstellung und erfolgreiche Dokumentuploads.

Creating or updating index 'hotels-vector-quickstart'...
Index 'hotels-vector-quickstart' updated.

Key: 1, Succeeded: True
Key: 2, Succeeded: True
Key: 3, Succeeded: True
Key: 4, Succeeded: True
Key: 48, Succeeded: True
Key: 49, Succeeded: True
Key: 13, Succeeded: True

Die Ausgabe des zweiten Projekts zeigt die Suchergebnisse für jede aktivierte Abfragemethode an. Das folgende Beispiel zeigt Einzelvektorsuchergebnisse.

Single Vector Search Results:
Score: 0.6605852, HotelId: 48, HotelName: Nordick's Valley Motel
Score: 0.6333684, HotelId: 13, HotelName: Luxury Lion Resort
Score: 0.605672, HotelId: 4, HotelName: Sublime Palace Hotel
Score: 0.6026341, HotelId: 49, HotelName: Swirling Currents Hotel
Score: 0.57902366, HotelId: 2, HotelName: Old Century Hotel

Grundlegendes zum Code

Hinweis

Möglicherweise wurden die Codeausschnitte in diesem Abschnitt zur Lesbarkeit geändert. Ein vollständiges Arbeitsbeispiel finden Sie im Quellcode.

Nachdem Sie den Code ausgeführt haben, lassen Sie uns die wichtigsten Schritte aufschlüsseln:

  1. Erstellen eines Vektorindexes
  2. Hochladen von Dokumenten in den Index
  3. Abfragen des Indexes

Erstellen eines Vektorindexes

Bevor Sie Inhalte zu Azure KI-Suche hinzufügen, müssen Sie einen Index erstellen, um zu definieren, wie der Inhalt gespeichert und strukturiert wird.

Das Indexschema ist um Hotelinhalte herum organisiert. Beispieldaten bestehen aus Vektor- und Nichtvektorbeschreibungen fiktiver Hotels. Der folgende Code in VectorSearchCreatePopulateIndex/Program.cs erstellt das Indexschema, einschließlich des Vektorfelds DescriptionVector.

static async Task CreateSearchIndex(string indexName, SearchIndexClient indexClient)
{
    var addressField = new ComplexField("Address");
    addressField.Fields.Add(new SearchableField("StreetAddress") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft });
    addressField.Fields.Add(new SearchableField("City") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });
    addressField.Fields.Add(new SearchableField("StateProvince") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });
    addressField.Fields.Add(new SearchableField("PostalCode") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });
    addressField.Fields.Add(new SearchableField("Country") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });

    var allFields = new List<SearchField>()
    {
        new SimpleField("HotelId", SearchFieldDataType.String) { IsKey = true, IsFacetable = true, IsFilterable = true },
        new SearchableField("HotelName") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft },
        new SearchableField("Description") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft },
        new VectorSearchField("DescriptionVector", 1536, "my-vector-profile"),
        new SearchableField("Category") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true },
        new SearchableField("Tags", collection: true) { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true },
        new SimpleField("ParkingIncluded", SearchFieldDataType.Boolean) { IsFacetable = true, IsFilterable = true },
        new SimpleField("LastRenovationDate", SearchFieldDataType.DateTimeOffset) { IsSortable = true },
        new SimpleField("Rating", SearchFieldDataType.Double) { IsFacetable = true, IsFilterable = true, IsSortable = true },
        addressField,
        new SimpleField("Location", SearchFieldDataType.GeographyPoint) { IsFilterable = true, IsSortable = true },
    };

    // Create the suggester configuration
    var suggester = new SearchSuggester("sg", new[] { "Address/City", "Address/Country" });

    // Create the semantic search
    var semanticSearch = new SemanticSearch()
    {
        Configurations =
        {
            new SemanticConfiguration(
                name: "semantic-config",
                prioritizedFields: new SemanticPrioritizedFields
                {
                    TitleField = new SemanticField("HotelName"),
                    KeywordsFields = { new SemanticField("Category") },
                    ContentFields = { new SemanticField("Description") }
                })
        }
    };

    // Add vector search configuration
    var vectorSearch = new VectorSearch();
    vectorSearch.Algorithms.Add(new HnswAlgorithmConfiguration(name: "my-hnsw-vector-config-1"));
    vectorSearch.Profiles.Add(new VectorSearchProfile(name: "my-vector-profile", algorithmConfigurationName: "my-hnsw-vector-config-1"));

    var definition = new SearchIndex(indexName)
    {
        Fields = allFields,
        Suggesters = { suggester },
        VectorSearch = vectorSearch,
        SemanticSearch = semanticSearch
    };

    // Create or update the index
    Console.WriteLine($"Creating or updating index '{indexName}'...");
    var result = await indexClient.CreateOrUpdateIndexAsync(definition);
    Console.WriteLine($"Index '{result.Value.Name}' updated.");
    Console.WriteLine();
}

Wichtige Erkenntnisse:

  • Sie definieren einen Index, indem Sie eine Liste von Feldern erstellen.

  • Dieser spezielle Index unterstützt mehrere Suchfunktionen:

  • Der zweite Parameter in VectorSearchField gibt vectorSearchDimensions an, das mit der Ausgabengröße Ihres Einbettungsmodells übereinstimmen muss. Diese Schnellstartanleitung verwendet 1.536 Dimensionen, um dem text-embedding-ada-002 Modell zu entsprechen.

  • Die VectorSearch Konfiguration definiert den Algorithmus für ungefähre nächste Nachbarn (ANN). Zu den unterstützten Algorithmen gehören Hierarchical Navigable Small World (HNSW) und exhaustives K-Nearest Neighbor (KNN). Weitere Informationen finden Sie unter Relevanz in der Vektorsuche.

Hochladen von Dokumenten in den Index

Neu erstellte Indizes sind leer. Um einen Index aufzufüllen und durchsuchbar zu machen, müssen Sie JSON-Dokumente hochladen, die dem Indexschema entsprechen.

In Azure KI-Suche dienen Dokumente sowohl als Eingaben für die Indizierung als auch als Ausgaben für Abfragen. Aus Gründen der Einfachheit bietet diese Schnellstartanleitung Beispiel-Hoteldokumente mit vorkompilierten Vektoren. In Produktionsszenarien werden Inhalte häufig aus verbundenen Datenquellen abgerufen und mithilfe von Indexern in JSON transformiert.

Der folgende Code lädt Dokumente von HotelData.json Ihrem Suchdienst hoch.

static async Task UploadDocs(SearchClient searchClient)
{
    var jsonPath = Path.Combine(Directory.GetCurrentDirectory(), "HotelData.json");

    // Read and parse hotel data
    var json = await File.ReadAllTextAsync(jsonPath);
    List<Hotel> hotels = new List<Hotel>();
    try
    {
        using var doc = JsonDocument.Parse(json);
        if (doc.RootElement.ValueKind != JsonValueKind.Array)
        {
            Console.WriteLine("HotelData.json root is not a JSON array.");
        }
        // Deserialize all hotel objects
        hotels = doc.RootElement.EnumerateArray()
            .Select(e => JsonSerializer.Deserialize<Hotel>(e.GetRawText()))
            .Where(h => h != null)
            .ToList();
    }
    catch (JsonException ex)
    {
        Console.WriteLine($"Failed to parse HotelData.json: {ex.Message}");
    }

    try
    {
        // Upload hotel documents to Azure Search
        var result = await searchClient.UploadDocumentsAsync(hotels);
        foreach (var r in result.Value.Results)
        {
            Console.WriteLine($"Key: {r.Key}, Succeeded: {r.Succeeded}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Failed to upload documents: " + ex);
    }
}

Ihr Code interagiert mit einem bestimmten Suchindex, der in Ihrem Azure KI-Suche-Dienst über das SearchClient gehostet wird, das hauptobjekt, das vom paket Azure.Search.Documents bereitgestellt wird. Der SearchClient Zugriff auf Indexvorgänge bietet, z. B.:

  • Datenaufnahme: UploadDocuments(), MergeDocuments()DeleteDocuments()

  • Suchvorgänge: Search(), Autocomplete()Suggest()

Abfragen des Indexes

Die Abfragen in VectorSearchExamples zeigen unterschiedliche Suchmuster. Die Beispielvektorabfragen basieren auf zwei Zeichenfolgen:

  • Volltext-Suchzeichenfolge: "historic hotel walk to restaurants and shopping"

  • Vektorabfragezeichenfolge: "quintessential lodging near running trails, eateries, retail" (in eine mathematische Darstellung vektorisiert)

Die Vektorabfragezeichenfolge ähnelt semantisch der Volltext-Suchzeichenfolge, enthält jedoch Ausdrücke, die nicht im Index vorhanden sind. Eine nur Schlüsselwortsuche nach der Vektorabfragezeichenfolge gibt null Ergebnisse zurück. Die Vektorsuche findet jedoch relevante Übereinstimmungen basierend auf bedeutungsbezogenen und nicht exakten Schlüsselwörtern.

Die folgenden Beispiele beginnen mit einer einfachen Vektorabfrage und fügen nach und nach Filter, Stichwortsuche und semantische Neuranking hinzu.

Die SearchSingleVector Methode veranschaulicht ein einfaches Szenario, in dem Sie Dokumentbeschreibungen finden möchten, die eng mit der Vektorabfragezeichenfolge übereinstimmen. VectorizedQuery konfiguriert die Vektorsuche:

  • KNearestNeighborsCount beschränkt, wie viele Ergebnisse basierend auf der Vektorähnlichkeit zurückgegeben werden.
  • Fields Gibt das zu durchsuchende Vektorfeld an.
public static async Task SearchSingleVector(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> response = await searchClient.SearchAsync<Hotel>(
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" },
        });

    Console.WriteLine($"Single Vector Search Results:");
    await foreach (SearchResult<Hotel> result in response.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}, HotelId: {doc.HotelId}, HotelName: {doc.HotelName}");
    }
    Console.WriteLine();
}

Einzelvektorsuche mit einem Filter

In Azure KI-Suche gelten Filter für Nichtvektorfelder in einem Index. Die SearchSingleVectorWithFilter Methode filtert auf dem Tags Feld, um Hotels herauszufiltern, die kein kostenloses WLAN bereitstellen.

public static async Task SearchSingleVectorWithFilter(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithFilter = await searchClient.SearchAsync<Hotel>(
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Filter = "Tags/any(tag: tag eq 'free wifi')",
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" }
        });

    Console.WriteLine($"Single Vector Search With Filter Results:");
    await foreach (SearchResult<Hotel> result in responseWithFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}, HotelId: {doc.HotelId}, HotelName: {doc.HotelName}, Tags: {string.Join(String.Empty, doc.Tags)}");
    }
    Console.WriteLine();
}

Einzelvektorsuche mit einem Geofilter

Sie können einen geo-räumlichen Filter angeben, um Die Ergebnisse auf einen bestimmten geografischen Bereich zu beschränken. Die SingleSearchWithGeoFilter Methode gibt einen geografischen Punkt (Washington D.C., mit Längengrad- und Breitenkoordinaten) an und gibt Hotels innerhalb von 300 Kilometern zurück. Standardmäßig werden Filter nach der Vektorsuche ausgeführt.

public static async Task SingleSearchWithGeoFilter(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithGeoFilter = await searchClient.SearchAsync<Hotel>(
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Filter = "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
            Select = { "HotelId", "HotelName", "Description", "Address", "Category", "Tags" },
            Facets = { "Address/StateProvince" },
        });

    Console.WriteLine($"Vector query with a geo filter:");
    await foreach (SearchResult<Hotel> result in responseWithGeoFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"HotelId: {doc.HotelId}");
        Console.WriteLine($"HotelName: {doc.HotelName}");
        Console.WriteLine($"Score: {result.Score}");
        Console.WriteLine($"City/State: {doc.Address.City}/{doc.Address.StateProvince}");
        Console.WriteLine($"Description: {doc.Description}");
        Console.WriteLine();
    }
    Console.WriteLine();
}

Die Hybridsuche kombiniert Volltext- und Vektorabfragen in einer einzigen Anforderung. Die SearchHybridVectorAndText Methode führt beide Abfragetypen gleichzeitig aus und verwendet dann reziproke Rangfusion (RRF), um die Ergebnisse in einer einheitlichen Rangfolge zusammenzuführen. RRF verwendet die Umkehrung der Ergebniseinstufungen aus jedem Resultset, um eine zusammengeführte Rangfolge zu erzeugen. Beachten Sie, dass hybride Suchergebnisse einheitlich kleiner als Einzelabfrageergebnisse sind.

public static async Task<SearchResults<Hotel>> SearchHybridVectorAndText(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithFilter = await searchClient.SearchAsync<Hotel>(
        "historic hotel walk to restaurants and shopping",
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" },
            Size = 5,
        });

    Console.WriteLine($"Hybrid search results:");
    await foreach (SearchResult<Hotel> result in responseWithFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}");
        Console.WriteLine($"HotelId: {doc.HotelId}");
        Console.WriteLine($"HotelName: {doc.HotelName}");
        Console.WriteLine($"Description: {doc.Description}");
        Console.WriteLine($"Category: {doc.Category}");
        Console.WriteLine($"Tags: {string.Join(String.Empty, doc.Tags)}");
        Console.WriteLine();
    }
    Console.WriteLine();
    return responseWithFilter;
}

Die SearchHybridVectorAndSemantic Methode demonstriert semantisches Ranking, das Ergebnisse basierend auf dem Sprachverständnis neu sortiert.

public static async Task SearchHybridVectorAndSemantic(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithFilter = await searchClient.SearchAsync<Hotel>(
        "historic hotel walk to restaurants and shopping",
        new SearchOptions
        {
            IncludeTotalCount = true,
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" },
            SemanticSearch = new SemanticSearchOptions
            {
                SemanticConfigurationName = "semantic-config"
            },
            QueryType = SearchQueryType.Semantic,
            Size = 5
        });

    Console.WriteLine($"Hybrid search results:");
    await foreach (SearchResult<Hotel> result in responseWithFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}");
        Console.WriteLine($"HotelId: {doc.HotelId}");
        Console.WriteLine($"HotelName: {doc.HotelName}");
        Console.WriteLine($"Description: {doc.Description}");
        Console.WriteLine($"Category: {doc.Category}");
        Console.WriteLine();
    }
    Console.WriteLine();
}

Vergleichen Sie diese Ergebnisse mit den Hybridsuchergebnissen aus der vorherigen Abfrage. Ohne semantisches Reranking rangiert das Sublime Palace Hotel zuerst, da die reziproke Rangfusion (RRF) die Text- und Vektorergebnisse kombiniert und ein zusammengeführtes Ergebnis erzeugt. Nach semantischem Reranking bewegt sich Swirling Currents Hotel an die Spitze.

Der semantische Rangfolger verwendet Computerverständnismodelle, um auszuwerten, wie gut jedes Ergebnis mit der Absicht der Abfrage übereinstimmt. Die Beschreibung des Swirling Currents Hotels erwähnt "walking access to shopping, dining, entertainment and the city center", die eng mit den Suchabfragen "walk to restaurants and shopping" übereinstimmt. Diese semantische Übereinstimmung für nahegelegene Restaurants und Einkaufsmöglichkeiten stellt es über das Sublime Palace Hotel, im Gegensatz zu dem Sublime Palace Hotel, das in seiner Beschreibung keine begehbaren Annehmlichkeiten hervorhebt.

Wichtige Erkenntnisse:

  • In einer Hybridsuche können Sie die Vektorsuche in die Volltextsuche über Schlüsselwörter integrieren. Filter und semantische Rangfolge gelten nur für Textinhalte, nicht für Vektoren.

  • Tatsächliche Ergebnisse umfassen weitere Details, einschließlich semantischer Beschriftungen und Hervorhebungen. In diesem Schnellstart werden die Ergebnisse zur besseren Lesbarkeit angepasst. Verwenden Sie REST, um die vollständige Struktur der Antwort abzurufen, um die Anforderung auszuführen.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, ist es ratsam, ein Projekt abzuschließen, indem Sie die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterlaufen, können Ihnen Geld kosten.

Wählen Sie im Azure Portal All resources or Resource groups aus dem linken Bereich aus, um Ressourcen zu suchen und zu verwalten. Sie können Ressourcen einzeln löschen oder die Ressourcengruppe löschen, um alle Ressourcen gleichzeitig zu entfernen.

In dieser Schnellstartanleitung verwenden Sie die Azure KI-Suche-Clientbibliothek für Java zum Erstellen, Laden und Abfragen eines vectorindex. Die Java-Clientbibliothek bietet eine Abstraktion über die REST-APIs für Indexvorgänge.

In Azure KI-Suche verfügt ein Vektorindex über ein Indexschema, das Vektor- und Nichtvektorfelder definiert, eine Vektorsuchkonfiguration für Algorithmen, die den Einbettungsraum erstellen, sowie Einstellungen für Vektorfelddefinitionen, die zur Abfragezeit ausgewertet werden. Indizes – Erstellen oder Aktualisieren (REST-API) erstellt den Vektorindex.

Tipp

Voraussetzungen

Konfigurieren des Zugriffs

Bevor Sie beginnen, stellen Sie sicher, dass Sie über Berechtigungen für den Zugriff auf Inhalte und Vorgänge in Azure KI-Suche verfügen. In dieser Schnellstartanleitung werden Microsoft Entra ID für die Authentifizierung und den rollenbasierten Zugriff für die Autorisierung verwendet. Sie müssen ein Besitzer oder Benutzerzugriffsadministrator sein, um Rollen zuzuweisen. Wenn Rollen nicht machbar sind, verwenden Sie stattdessen die schlüsselbasierte Authentifizierung .

So konfigurieren Sie den empfohlenen rollenbasierten Zugriff:

  1. Aktivieren Sie den rollenbasierten Zugriff für Ihren Suchdienst.

  2. Weisen Sie Ihrem Benutzerkonto die folgenden Rollen zu.

    • Suchdienstmitwirkender

    • Datenbeitragender für den Suchindex

    • Suchindexdatenleser

Endpunkt abrufen

Jeder Azure KI-Suche Dienst verfügt über einen endpoint, einer eindeutigen URL, die den Netzwerkzugriff auf den Dienst identifiziert und bereitstellt. In einem späteren Abschnitt geben Sie diesen Endpunkt an, um programmgesteuert eine Verbindung mit Ihrem Suchdienst herzustellen.

So rufen Sie den Endpunkt ab:

  1. Wechseln Sie zum Suchdienst im Azure-Portal.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich den Endpunkt, der wie https://my-service.search.windows.net folgt aussehen wird.

Einrichten der Umgebung

  1. Verwenden Sie Git, um das Beispiel-Repository zu klonen.

    git clone https://github.com/Azure-Samples/azure-search-java-samples
    
  2. Navigieren Sie zum Schnellstartordner.

    cd azure-search-java-samples/quickstart-vector-search
    
  3. In src/main/resources/application.properties ersetzen Sie den Platzhalterwert durch die URL, die Sie im Get-Endpunkt in azure.search.endpoint abgerufen haben.

  4. Installieren Sie die Abhängigkeiten.

    mvn clean dependency:copy-dependencies
    

    Nach Abschluss des Builds sollte ein target/dependency Ordner im Projektverzeichnis angezeigt werden.

  5. Melden Sie sich für die schlüssellose Authentifizierung mit Microsoft Entra ID bei Ihrem Azure-Konto an. Wenn Sie über mehrere Abonnements verfügen, wählen Sie das Abonnement aus, das Ihren Azure KI-Suche Dienst enthält.

    az login
    

Ausführen des Codes

  1. Erstellen Sie einen Vektorindex.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.CreateIndex"
    
  2. Laden Sie Dokumente, die vorkompilierte Einbettungen enthalten.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.UploadDocuments"
    
  3. Führen Sie eine Vektorsuchabfrage aus.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingle"
    
  4. (Optional) Führen Sie zusätzliche Abfragevariationen aus.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingleWithFilter"
    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingleWithFilterGeo"
    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchHybrid"
    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSemanticHybrid"
    

Ausgabe

Die Ausgabe von CreateIndex.java zeigt den Indexnamen und die Bestätigung an.

Using Azure Search endpoint: https://<search-service-name>.search.windows.net
Using Azure Search index: hotels-vector-quickstart
Creating index...
hotels-vector-quickstart created

Die Ausgabe von UploadDocuments.java zeigt den Erfolgsstatus für jedes indizierte Dokument.

Uploading documents...
Key: 1, Succeeded: true, ErrorMessage: none
Key: 2, Succeeded: true, ErrorMessage: none
Key: 3, Succeeded: true, ErrorMessage: none
Key: 4, Succeeded: true, ErrorMessage: none
Key: 48, Succeeded: true, ErrorMessage: none
Key: 49, Succeeded: true, ErrorMessage: none
Key: 13, Succeeded: true, ErrorMessage: none
Waiting for indexing... Current count: 0
All documents indexed successfully.

Die Ausgabe von SearchSingle.java zeigt Vektorsuchergebnisse, die nach Ähnlichkeitswert bewertet sind.

Single Vector search found 5
- HotelId: 48, HotelName: Nordick's Valley Motel, Tags: ["continental breakfast","air conditioning","free wifi"], Score 0.6605852
- HotelId: 13, HotelName: Luxury Lion Resort, Tags: ["bar","concierge","restaurant"], Score 0.6333684
- HotelId: 4, HotelName: Sublime Palace Hotel, Tags: ["concierge","view","air conditioning"], Score 0.605672
- HotelId: 49, HotelName: Swirling Currents Hotel, Tags: ["air conditioning","laundry service","24-hour front desk service"], Score 0.6026341
- HotelId: 2, HotelName: Old Century Hotel, Tags: ["pool","free wifi","air conditioning","concierge"], Score 0.57902366

Grundlegendes zum Code

Hinweis

Möglicherweise wurden die Codeausschnitte in diesem Abschnitt zur Lesbarkeit geändert. Ein vollständiges Arbeitsbeispiel finden Sie im Quellcode.

Nachdem Sie den Code ausgeführt haben, lassen Sie uns die wichtigsten Schritte aufschlüsseln:

  1. Erstellen eines Vektorindexes
  2. Hochladen von Dokumenten in den Index
  3. Abfragen des Indexes

Erstellen eines Vektorindexes

Bevor Sie Inhalte zu Azure KI-Suche hinzufügen, müssen Sie einen Index erstellen, um zu definieren, wie der Inhalt gespeichert und strukturiert wird.

Das Indexschema ist um Hotelinhalte herum organisiert. Beispieldaten bestehen aus Vektor- und Nichtvektorbeschreibungen fiktiver Hotels. Der folgende Code in CreateIndex.java erstellt das Indexschema, einschließlich des Vektorfelds DescriptionVector.

// Define fields
List<SearchField> fields = Arrays.asList(
    new SearchField("HotelId", SearchFieldDataType.STRING)
        .setKey(true)
        .setFilterable(true),
    new SearchField("HotelName", SearchFieldDataType.STRING)
        .setSortable(true)
        .setSearchable(true),
    new SearchField("Description", SearchFieldDataType.STRING)
        .setSearchable(true),
    new SearchField("DescriptionVector",
        SearchFieldDataType.collection(SearchFieldDataType.SINGLE))
        .setSearchable(true)
        .setVectorSearchDimensions(1536)
        .setVectorSearchProfileName("my-vector-profile"),
    new SearchField("Category", SearchFieldDataType.STRING)
        .setSortable(true)
        .setFilterable(true)
        .setFacetable(true)
        .setSearchable(true),
    new SearchField("Tags", SearchFieldDataType.collection(
        SearchFieldDataType.STRING))
        .setSearchable(true)
        .setFilterable(true)
        .setFacetable(true),
    // Additional fields: ParkingIncluded, LastRenovationDate, Rating, Address, Location
);

var searchIndex = new SearchIndex(indexName, fields);

// Define vector search configuration
var hnswParams = new HnswParameters()
    .setM(16)
    .setEfConstruction(200)
    .setEfSearch(128);
var hnsw = new HnswAlgorithmConfiguration("hnsw-vector-config");
hnsw.setParameters(hnswParams);

var vectorProfile = new VectorSearchProfile(
    "my-vector-profile",
    "hnsw-vector-config");
var vectorSearch = new VectorSearch()
    .setAlgorithms(Arrays.asList(hnsw))
    .setProfiles(Arrays.asList(vectorProfile));
searchIndex.setVectorSearch(vectorSearch);

// Define semantic configuration
var prioritizedFields = new SemanticPrioritizedFields()
    .setTitleField(new SemanticField("HotelName"))
    .setContentFields(Arrays.asList(new SemanticField("Description")))
    .setKeywordsFields(Arrays.asList(new SemanticField("Category")));
var semanticConfig = new SemanticConfiguration(
    "semantic-config",
    prioritizedFields);
var semanticSearch = new SemanticSearch()
    .setConfigurations(Arrays.asList(semanticConfig));
searchIndex.setSemanticSearch(semanticSearch);

// Define suggesters
var suggester = new SearchSuggester("sg", Arrays.asList("HotelName"));
searchIndex.setSuggesters(Arrays.asList(suggester));

// Create the search index
SearchIndex result = searchIndexClient.createOrUpdateIndex(searchIndex);

Wichtige Erkenntnisse:

  • Sie definieren einen Index, indem Sie eine Liste von Feldern erstellen.

  • Dieser spezielle Index unterstützt mehrere Suchfunktionen:

  • Der setVectorSearchDimensions() Wert muss mit der Ausgabegröße Ihres Einbettungsmodells übereinstimmen. Diese Schnellstartanleitung verwendet 1.536 Dimensionen, um dem text-embedding-ada-002 Modell zu entsprechen.

  • Die VectorSearch Konfiguration definiert den Algorithmus für ungefähre nächste Nachbarn (ANN). Zu den unterstützten Algorithmen gehören Hierarchical Navigable Small World (HNSW) und exhaustives K-Nearest Neighbor (KNN). Weitere Informationen finden Sie unter Relevanz in der Vektorsuche.

Hochladen von Dokumenten in den Index

Neu erstellte Indizes sind leer. Um einen Index aufzufüllen und durchsuchbar zu machen, müssen Sie JSON-Dokumente hochladen, die dem Indexschema entsprechen.

In Azure KI-Suche dienen Dokumente sowohl als Eingaben für die Indizierung als auch als Ausgaben für Abfragen. Aus Gründen der Einfachheit bietet diese Schnellstartanleitung Beispiel-Hoteldokumente mit vorkompilierten Vektoren. In Produktionsszenarien werden Inhalte häufig aus verbundenen Datenquellen abgerufen und mithilfe von Indexern in JSON transformiert.

Der folgende Code in UploadDocuments.java lädt Dokumente in Ihren Suchdienst hoch.

// Documents contain hotel data with 1536-dimension vectors for DescriptionVector
static final List<Map<String, Object>> DOCUMENTS = Arrays.asList(
    new HashMap<>() {{
        put("@search.action", "mergeOrUpload");
        put("HotelId", "1");
        put("HotelName", "Stay-Kay City Hotel");
        put("Description", "This classic hotel is fully-refurbished...");
        put("DescriptionVector", Arrays.asList(/* 1536 float values */));
        put("Category", "Boutique");
        put("Tags", Arrays.asList("view", "air conditioning", "concierge"));
        // Additional fields...
    }}
    // Additional hotel documents
);

// Upload documents to the index
IndexDocumentsResult result = searchClient.uploadDocuments(DOCUMENTS);
for (IndexingResult r : result.getResults()) {
    System.out.println("Key: %s, Succeeded: %s".formatted(r.getKey(), r.isSucceeded()));
}

Ihr Code interagiert mit einem bestimmten Suchindex, der in Ihrem Azure KI-Suche-Dienst über das SearchClient gehostet wird, das hauptobjekt, das vom paket azure-search-documents bereitgestellt wird. Der SearchClient bietet Zugriff auf Vorgänge wie:

  • Datenaufnahme: uploadDocuments, mergeDocumentsdeleteDocuments

  • Suchvorgänge: search, autocompletesuggest

Abfragen des Indexes

Die Abfragen in den Suchdateien veranschaulichen unterschiedliche Suchmuster. Die Beispielvektorabfragen basieren auf zwei Zeichenfolgen:

  • Volltext-Suchzeichenfolge: "historic hotel walk to restaurants and shopping"

  • Vektorabfragezeichenfolge: "quintessential lodging near running trails, eateries, retail" (in eine mathematische Darstellung vektorisiert)

Die Vektorabfragezeichenfolge ähnelt semantisch der Volltext-Suchzeichenfolge, enthält jedoch Ausdrücke, die nicht im Index vorhanden sind. Eine nur Schlüsselwortsuche nach der Vektorabfragezeichenfolge gibt null Ergebnisse zurück. Die Vektorsuche findet jedoch relevante Übereinstimmungen basierend auf bedeutungsbezogenen und nicht exakten Schlüsselwörtern.

Die folgenden Beispiele beginnen mit einer einfachen Vektorabfrage und fügen nach und nach Filter, Stichwortsuche und semantische Neuranking hinzu.

SearchSingle.java veranschaulicht ein einfaches Szenario, in dem Sie Dokumentbeschreibungen finden möchten, die eng mit der Vektorabfragezeichenfolge übereinstimmen. VectorizedQuery konfiguriert die Vektorsuche:

  • setKNearestNeighborsCount() beschränkt, wie viele Ergebnisse basierend auf der Vektorähnlichkeit zurückgegeben werden.
  • setFields() Gibt das zu durchsuchende Vektorfeld an.
var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

var searchOptions = new SearchOptions()
    .setTop(7)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Description", "Category", "Tags")
    .setVectorSearchOptions(vectorSearchOptions);

var results = searchClient.search("*", searchOptions, Context.NONE);

for (SearchResult result : results) {
    SearchDocument document = result.getDocument(SearchDocument.class);
    System.out.println("HotelId: %s, HotelName: %s, Score: %s".formatted(
        document.get("HotelId"), document.get("HotelName"), result.getScore()));
}

Einzelvektorsuche mit einem Filter

In Azure KI-Suche gelten Filter für Nichtvektorfelder in einem Index. SearchSingleWithFilter.java filtert auf dem Tags Feld, um Hotels herauszufiltern, die kein kostenloses WLAN bieten.

var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

// Add filter for "free wifi" tag
var searchOptions = new SearchOptions()
    .setTop(7)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Description", "Category", "Tags")
    .setFilter("Tags/any(tag: tag eq 'free wifi')")
    .setVectorSearchOptions(vectorSearchOptions);

var results = searchClient.search("*", searchOptions, Context.NONE);

Einzelvektorsuche mit einem Geofilter

Sie können einen geo-räumlichen Filter angeben, um Die Ergebnisse auf einen bestimmten geografischen Bereich zu beschränken. SearchSingleWithGeoFilter.java Gibt einen geografischen Punkt (Washington D.C., mit Längen- und Breitengradkoordinaten) an und gibt Hotels innerhalb von 300 Kilometern zurück. Die setFilterMode Methode, die VectorSearchOptionsaufgerufen wird, bestimmt, wann der Filter ausgeführt wird. In diesem Fall führt POST_FILTER den Filter nach der Vektorsuche aus.

var searchOptions = new SearchOptions()
    .setTop(5)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Category", "Description",
               "Address/City", "Address/StateProvince")
    .setFacets("Address/StateProvince")
    .setFilter("geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300")
    .setVectorSearchOptions(vectorSearchOptions);

Die Hybridsuche kombiniert Volltext- und Vektorabfragen in einer einzigen Anforderung. SearchHybrid.java führt beide Abfragetypen gleichzeitig aus und verwendet dann reziprozien Rangfusion (RRF), um die Ergebnisse in einer einheitlichen Rangfolge zusammenzuführen. RRF verwendet die Umkehrung der Ergebniseinstufungen aus jedem Resultset, um eine zusammengeführte Rangfolge zu erzeugen. Beachten Sie, dass hybride Suchergebnisse einheitlich kleiner als Einzelabfrageergebnisse sind.

var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

var searchOptions = new SearchOptions()
    .setTop(5)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Description", "Category", "Tags")
    .setVectorSearchOptions(vectorSearchOptions);

// Pass both text query and vector search options
var results = searchClient.search(
    "historic hotel walk to restaurants and shopping",
    searchOptions, Context.NONE);

SearchSemanticHybrid.java veranschaulicht die semantische Rangfolge, die Ergebnisse basierend auf dem Sprachverständnis neu anordnet.

var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

SemanticSearchOptions semanticSearchOptions = new SemanticSearchOptions()
    .setSemanticConfigurationName("semantic-config");

var searchOptions = new SearchOptions()
    .setTop(5)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Category", "Description")
    .setQueryType(QueryType.SEMANTIC)
    .setSemanticSearchOptions(semanticSearchOptions)
    .setVectorSearchOptions(vectorSearchOptions);

var results = searchClient.search(
    "historic hotel walk to restaurants and shopping",
    searchOptions, Context.NONE);

Vergleichen Sie diese Ergebnisse mit den Hybridsuchergebnissen aus der vorherigen Abfrage. Ohne semantisches Reranking rangiert das Sublime Palace Hotel zuerst, da die reziproke Rangfusion (RRF) die Text- und Vektorergebnisse kombiniert und ein zusammengeführtes Ergebnis erzeugt. Nach semantischem Reranking bewegt sich Swirling Currents Hotel an die Spitze.

Der semantische Rangfolger verwendet Computerverständnismodelle, um auszuwerten, wie gut jedes Ergebnis mit der Absicht der Abfrage übereinstimmt. Die Beschreibung des Swirling Currents Hotels erwähnt "walking access to shopping, dining, entertainment and the city center", die eng mit den Suchabfragen "walk to restaurants and shopping" übereinstimmt. Diese semantische Übereinstimmung für nahegelegene Restaurants und Einkaufsmöglichkeiten stellt es über das Sublime Palace Hotel, im Gegensatz zu dem Sublime Palace Hotel, das in seiner Beschreibung keine begehbaren Annehmlichkeiten hervorhebt.

Wichtige Erkenntnisse:

  • In einer Hybridsuche können Sie die Vektorsuche in die Volltextsuche über Schlüsselwörter integrieren. Filter und semantische Rangfolge gelten nur für Textinhalte, nicht für Vektoren.

  • Tatsächliche Ergebnisse umfassen weitere Details, einschließlich semantischer Beschriftungen und Hervorhebungen. In diesem Schnellstart werden die Ergebnisse zur besseren Lesbarkeit angepasst. Verwenden Sie REST, um die vollständige Struktur der Antwort abzurufen, um die Anforderung auszuführen.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, ist es ratsam, ein Projekt abzuschließen, indem Sie die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterlaufen, können Ihnen Geld kosten.

Wählen Sie im Azure Portal All resources or Resource groups aus dem linken Bereich aus, um Ressourcen zu suchen und zu verwalten. Sie können Ressourcen einzeln löschen oder die Ressourcengruppe löschen, um alle Ressourcen gleichzeitig zu entfernen.

Führen Sie andernfalls den folgenden Befehl aus, um den in dieser Schnellstartanleitung erstellten Index zu löschen.

mvn compile exec:java "-Dexec.mainClass=com.example.search.DeleteIndex"

In dieser Schnellstartanleitung verwenden Sie die Azure KI-Suche-Clientbibliothek für JavaScript zum Erstellen, Laden und Abfragen eines vectorindex. Die JavaScript-Clientbibliothek bietet eine Abstraktion über die REST-APIs für Indexvorgänge.

In Azure KI-Suche verfügt ein Vektorindex über ein Indexschema, das Vektor- und Nichtvektorfelder definiert, eine Vektorsuchkonfiguration für Algorithmen, die den Einbettungsraum erstellen, sowie Einstellungen für Vektorfelddefinitionen, die zur Abfragezeit ausgewertet werden. Indizes – Erstellen oder Aktualisieren (REST-API) erstellt den Vektorindex.

Tipp

Voraussetzungen

  • Ein Azure Konto mit einem aktiven Abonnement. Erstellen Sie kostenlos ein Konto.

  • Ein Azure KI-Suche-Dienst. Sie können die Kostenlose Ebene für die meisten dieser Schnellstartanleitungen verwenden, aber wir empfehlen Basic oder höher für größere Datendateien.

  • Node.js 20 LTS oder höher.

  • Git um das Beispiel-Repository zu klonen.

  • Die Azure CLI für die schlüssellose Authentifizierung mit Microsoft Entra ID.

Konfigurieren des Zugriffs

Bevor Sie beginnen, stellen Sie sicher, dass Sie über Berechtigungen für den Zugriff auf Inhalte und Vorgänge in Azure KI-Suche verfügen. In dieser Schnellstartanleitung werden Microsoft Entra ID für die Authentifizierung und den rollenbasierten Zugriff für die Autorisierung verwendet. Sie müssen ein Besitzer oder Benutzerzugriffsadministrator sein, um Rollen zuzuweisen. Wenn Rollen nicht machbar sind, verwenden Sie stattdessen die schlüsselbasierte Authentifizierung .

So konfigurieren Sie den empfohlenen rollenbasierten Zugriff:

  1. Aktivieren Sie den rollenbasierten Zugriff für Ihren Suchdienst.

  2. Weisen Sie Ihrem Benutzerkonto die folgenden Rollen zu.

    • Suchdienstmitwirkender

    • Datenbeitragender für den Suchindex

    • Suchindexdatenleser

Endpunkt abrufen

Jeder Azure KI-Suche Dienst verfügt über einen endpoint, einer eindeutigen URL, die den Netzwerkzugriff auf den Dienst identifiziert und bereitstellt. In einem späteren Abschnitt geben Sie diesen Endpunkt an, um programmgesteuert eine Verbindung mit Ihrem Suchdienst herzustellen.

So rufen Sie den Endpunkt ab:

  1. Wechseln Sie zum Suchdienst im Azure-Portal.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich den Endpunkt, der wie https://my-service.search.windows.net folgt aussehen wird.

Einrichten der Umgebung

  1. Verwenden Sie Git, um das Beispiel-Repository zu klonen.

    git clone https://github.com/Azure-Samples/azure-search-javascript-samples
    
  2. Navigieren Sie zum Schnellstartordner.

    cd azure-search-javascript-samples/quickstart-vector-js
    
  3. In sample.env ersetzen Sie den Platzhalterwert durch die URL, die Sie im Get-Endpunkt in AZURE_SEARCH_ENDPOINT abgerufen haben.

  4. Umbenennen sample.env in .env.

    mv sample.env .env
    
  5. Installieren Sie die Abhängigkeiten.

    npm install
    

    Nach Abschluss der Installation sollte ein node_modules Ordner im Projektverzeichnis angezeigt werden.

  6. Melden Sie sich für die schlüssellose Authentifizierung mit Microsoft Entra ID bei Ihrem Azure-Konto an. Wenn Sie über mehrere Abonnements verfügen, wählen Sie das Abonnement aus, das Ihren Azure KI-Suche Dienst enthält.

    az login
    

Ausführen des Codes

  1. Erstellen Sie einen Vektorindex.

    node -r dotenv/config src/createIndex.js
    
  2. Laden Sie Dokumente, die vorkompilierte Einbettungen enthalten.

    node -r dotenv/config src/uploadDocuments.js
    
  3. Führen Sie eine Vektorsuchabfrage aus.

    node -r dotenv/config src/searchSingle.js
    
  4. (Optional) Führen Sie zusätzliche Abfragevariationen aus.

    node -r dotenv/config src/searchSingleWithFilter.js
    node -r dotenv/config src/searchSingleWithFilterGeo.js
    node -r dotenv/config src/searchHybrid.js
    node -r dotenv/config src/searchSemanticHybrid.js
    

Ausgabe

Die Ausgabe von createIndex.js zeigt den Indexnamen und die Bestätigung an.

Using Azure Search endpoint: https://<search-service-name>.search.windows.net
Using Azure Search index: hotels-vector-quickstart
Creating index...
hotels-vector-quickstart created

Die Ausgabe von uploadDocuments.js zeigt den Erfolgsstatus für jedes indizierte Dokument.

Uploading documents...
Key: 1, Succeeded: true, ErrorMessage: none
Key: 2, Succeeded: true, ErrorMessage: none
Key: 3, Succeeded: true, ErrorMessage: none
Key: 4, Succeeded: true, ErrorMessage: none
Key: 48, Succeeded: true, ErrorMessage: none
Key: 49, Succeeded: true, ErrorMessage: none
Key: 13, Succeeded: true, ErrorMessage: none
Waiting for indexing... Current count: 0
All documents indexed successfully.

Die Ausgabe von searchSingle.js zeigt Vektorsuchergebnisse, die nach Ähnlichkeitswert bewertet sind.

Single Vector search found 5
- HotelId: 48, HotelName: Nordick's Valley Motel, Tags: ["continental breakfast","air conditioning","free wifi"], Score 0.6605852
- HotelId: 13, HotelName: Luxury Lion Resort, Tags: ["bar","concierge","restaurant"], Score 0.6333684
- HotelId: 4, HotelName: Sublime Palace Hotel, Tags: ["concierge","view","air conditioning"], Score 0.605672
- HotelId: 49, HotelName: Swirling Currents Hotel, Tags: ["air conditioning","laundry service","24-hour front desk service"], Score 0.6026341
- HotelId: 2, HotelName: Old Century Hotel, Tags: ["pool","free wifi","air conditioning","concierge"], Score 0.57902366

Grundlegendes zum Code

Hinweis

Möglicherweise wurden die Codeausschnitte in diesem Abschnitt zur Lesbarkeit geändert. Ein vollständiges Arbeitsbeispiel finden Sie im Quellcode.

Nachdem Sie den Code ausgeführt haben, lassen Sie uns die wichtigsten Schritte aufschlüsseln:

  1. Erstellen eines Vektorindexes
  2. Hochladen von Dokumenten in den Index
  3. Abfragen des Indexes

Erstellen eines Vektorindexes

Bevor Sie Inhalte zu Azure KI-Suche hinzufügen, müssen Sie einen Index erstellen, um zu definieren, wie der Inhalt gespeichert und strukturiert wird.

Das Indexschema ist um Hotelinhalte herum organisiert. Beispieldaten bestehen aus Vektor- und Nichtvektorbeschreibungen fiktiver Hotels. Der folgende Code in createIndex.js erstellt das Indexschema, einschließlich des Vektorfelds DescriptionVector.

const searchFields = [
    { name: "HotelId", type: "Edm.String", key: true, sortable: true, filterable: true, facetable: true },
    { name: "HotelName", type: "Edm.String", searchable: true, filterable: true },
    { name: "Description", type: "Edm.String", searchable: true },
    {
        name: "DescriptionVector",
        type: "Collection(Edm.Single)",
        searchable: true,
        vectorSearchDimensions: 1536,
        vectorSearchProfileName: "vector-profile"
    },
    { name: "Category", type: "Edm.String", filterable: true, facetable: true },
    { name: "Tags", type: "Collection(Edm.String)", filterable: true },
    // Additional fields: ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const vectorSearch = {
    profiles: [
        {
            name: "vector-profile",
            algorithmConfigurationName: "vector-search-algorithm"
        }
    ],
    algorithms: [
        {
            name: "vector-search-algorithm",
            kind: "hnsw",
            parameters: { m: 4, efConstruction: 400, efSearch: 1000, metric: "cosine" }
        }
    ]
};

const semanticSearch = {
    configurations: [
        {
            name: "semantic-config",
            prioritizedFields: {
                contentFields: [{ name: "Description" }],
                keywordsFields: [{ name: "Category" }],
                titleField: { name: "HotelName" }
            }
        }
    ]
};

const searchIndex = {
    name: indexName,
    fields: searchFields,
    vectorSearch: vectorSearch,
    semanticSearch: semanticSearch,
    suggesters: [{ name: "sg", searchMode: "analyzingInfixMatching", sourceFields: ["HotelName"] }]
};

const result = await indexClient.createOrUpdateIndex(searchIndex);

Wichtige Erkenntnisse:

  • Sie definieren einen Index, indem Sie eine Liste von Feldern erstellen.

  • Dieser spezielle Index unterstützt mehrere Suchfunktionen:

  • Die vectorSearchDimensions Eigenschaft muss mit der Ausgabegröße Ihres Einbettungsmodells übereinstimmen. Diese Schnellstartanleitung verwendet 1.536 Dimensionen, um dem text-embedding-ada-002 Modell zu entsprechen.

  • Die vectorSearch Konfiguration definiert den Algorithmus für ungefähre nächste Nachbarn (ANN). Zu den unterstützten Algorithmen gehören Hierarchical Navigable Small World (HNSW) und exhaustives K-Nearest Neighbor (KNN). Weitere Informationen finden Sie unter Relevanz in der Vektorsuche.

Hochladen von Dokumenten in den Index

Neu erstellte Indizes sind leer. Um einen Index aufzufüllen und durchsuchbar zu machen, müssen Sie JSON-Dokumente hochladen, die dem Indexschema entsprechen.

In Azure KI-Suche dienen Dokumente sowohl als Eingaben für die Indizierung als auch als Ausgaben für Abfragen. Aus Gründen der Einfachheit bietet diese Schnellstartanleitung Beispiel-Hoteldokumente mit vorkompilierten Vektoren. In Produktionsszenarien werden Inhalte häufig aus verbundenen Datenquellen abgerufen und mithilfe von Indexern in JSON transformiert.

Der folgende Code in uploadDocuments.js lädt Dokumente in Ihren Suchdienst hoch.

const DOCUMENTS = [
    // Array of hotel documents with embedded 1536-dimension vectors
    // Each document contains: HotelId, HotelName, Description, DescriptionVector,
    // Category, Tags, ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const searchClient = new SearchClient(searchEndpoint, indexName, credential);

const result = await searchClient.uploadDocuments(DOCUMENTS);
for (const r of result.results) {
    console.log(`Key: ${r.key}, Succeeded: ${r.succeeded}`);
}

Ihr Code interagiert mit einem bestimmten Suchindex, der in Ihrem Azure KI-Suche-Dienst über das SearchClient gehostet wird, das hauptobjekt, das vom paket @azure/search-documents bereitgestellt wird. Der SearchClient Zugriff auf Indexvorgänge bietet, z. B.:

  • Datenaufnahme: uploadDocuments, mergeDocumentsdeleteDocuments

  • Suchvorgänge: search, autocompletesuggest

Abfragen des Indexes

Die Abfragen in den Suchdateien veranschaulichen unterschiedliche Suchmuster. Die Beispielvektorabfragen basieren auf zwei Zeichenfolgen:

  • Volltext-Suchzeichenfolge: "historic hotel walk to restaurants and shopping"

  • Vektorabfragezeichenfolge: "quintessential lodging near running trails, eateries, retail" (in eine mathematische Darstellung vektorisiert)

Die Vektorabfragezeichenfolge ähnelt semantisch der Volltext-Suchzeichenfolge, enthält jedoch Ausdrücke, die nicht im Index vorhanden sind. Eine nur Schlüsselwortsuche nach der Vektorabfragezeichenfolge gibt null Ergebnisse zurück. Die Vektorsuche findet jedoch relevante Übereinstimmungen basierend auf bedeutungsbezogenen und nicht exakten Schlüsselwörtern.

Die folgenden Beispiele beginnen mit einer einfachen Vektorabfrage und fügen nach und nach Filter, Stichwortsuche und semantische Neuranking hinzu.

searchSingle.js veranschaulicht ein einfaches Szenario, in dem Sie Dokumentbeschreibungen finden möchten, die eng mit der Vektorabfragezeichenfolge übereinstimmen. Das vectorQuery Objekt konfiguriert die Vektorsuche:

  • kNearestNeighborsCount beschränkt, wie viele Ergebnisse basierend auf der Vektorähnlichkeit zurückgegeben werden.
  • fields Gibt das zu durchsuchende Vektorfeld an.
const vectorQuery = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"],
    includeTotalCount: true,
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results = await searchClient.search("*", searchOptions);

for await (const result of results.results) {
    const doc = result.document;
    console.log(`HotelId: ${doc.HotelId}, HotelName: ${doc.HotelName}, Score: ${result.score}`);
}

Einzelvektorsuche mit einem Filter

In Azure KI-Suche gelten Filter für Nichtvektorfelder in einem Index. searchSingleWithFilter.js filtert auf dem Tags Feld, um Hotels herauszufiltern, die kein kostenloses WLAN bieten.

const searchOptions = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"],
    includeTotalCount: true,
    filter: "Tags/any(tag: tag eq 'free wifi')", // Adding filter for "free wifi" tag
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results = await searchClient.search("*", searchOptions);

Einzelvektorsuche mit einem Geofilter

Sie können einen geo-räumlichen Filter angeben, um Die Ergebnisse auf einen bestimmten geografischen Bereich zu beschränken. searchSingleWithGeoFilter.js Gibt einen geografischen Punkt (Washington D.C., mit Längen- und Breitengradkoordinaten) an und gibt Hotels innerhalb von 300 Kilometern zurück. Die filterMode Eigenschaft bestimmt, wann der Filter ausgeführt wird. In diesem Fall führt postFilter den Filter nach der Vektorsuche aus.

const searchOptions = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description", "Address/City", "Address/StateProvince"],
    facets: ["Address/StateProvince"],
    filter: "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

Die Hybridsuche kombiniert Volltext- und Vektorabfragen in einer einzigen Anforderung. searchHybrid.js führt beide Abfragetypen gleichzeitig aus und verwendet dann reziprozien Rangfusion (RRF), um die Ergebnisse in einer einheitlichen Rangfolge zusammenzuführen. RRF verwendet die Umkehrung der Ergebniseinstufungen aus jedem Resultset, um eine zusammengeführte Rangfolge zu erzeugen. Beachten Sie, dass hybride Suchergebnisse einheitlich kleiner als Einzelabfrageergebnisse sind.

const vectorQuery = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"],
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

// Use search text for keyword search (hybrid search = vector + keyword)
const searchText = "historic hotel walk to restaurants and shopping";
const results = await searchClient.search(searchText, searchOptions);

searchSemanticHybrid.js veranschaulicht die semantische Rangfolge, die Ergebnisse basierend auf dem Sprachverständnis neu anordnet.

const searchOptions = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description"],
    queryType: "semantic",
    semanticSearchOptions: {
        configurationName: "semantic-config"
    },
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const searchText = "historic hotel walk to restaurants and shopping";
const results = await searchClient.search(searchText, searchOptions);

for await (const result of results.results) {
    console.log(`Score: ${result.score}, Re-ranker Score: ${result.rerankerScore}`);
}

Vergleichen Sie diese Ergebnisse mit den Hybridsuchergebnissen aus der vorherigen Abfrage. Ohne semantisches Reranking rangiert das Sublime Palace Hotel zuerst, da die reziproke Rangfusion (RRF) die Text- und Vektorergebnisse kombiniert und ein zusammengeführtes Ergebnis erzeugt. Nach semantischem Reranking bewegt sich Swirling Currents Hotel an die Spitze.

Der semantische Rangfolger verwendet Computerverständnismodelle, um auszuwerten, wie gut jedes Ergebnis mit der Absicht der Abfrage übereinstimmt. Die Beschreibung des Swirling Currents Hotels erwähnt "walking access to shopping, dining, entertainment and the city center", die eng mit den Suchabfragen "walk to restaurants and shopping" übereinstimmt. Diese semantische Übereinstimmung für nahegelegene Restaurants und Einkaufsmöglichkeiten stellt es über das Sublime Palace Hotel, im Gegensatz zu dem Sublime Palace Hotel, das in seiner Beschreibung keine begehbaren Annehmlichkeiten hervorhebt.

Wichtige Erkenntnisse:

  • In einer Hybridsuche können Sie die Vektorsuche in die Volltextsuche über Schlüsselwörter integrieren. Filter und semantische Rangfolge gelten nur für Textinhalte, nicht für Vektoren.

  • Tatsächliche Ergebnisse umfassen weitere Details, einschließlich semantischer Beschriftungen und Hervorhebungen. In diesem Schnellstart werden die Ergebnisse zur besseren Lesbarkeit angepasst. Verwenden Sie REST, um die vollständige Struktur der Antwort abzurufen, um die Anforderung auszuführen.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, ist es ratsam, ein Projekt abzuschließen, indem Sie die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterlaufen, können Ihnen Geld kosten.

Wählen Sie im Azure Portal All resources or Resource groups aus dem linken Bereich aus, um Ressourcen zu suchen und zu verwalten. Sie können Ressourcen einzeln löschen oder die Ressourcengruppe löschen, um alle Ressourcen gleichzeitig zu entfernen.

Führen Sie andernfalls den folgenden Befehl aus, um den in dieser Schnellstartanleitung erstellten Index zu löschen.

node -r dotenv/config src/deleteIndex.js

In dieser Schnellstartanleitung verwenden Sie die Azure KI-Suche-Clientbibliothek für Python zum Erstellen, Laden und Abfragen eines vectorindex. Die Python-Clientbibliothek bietet eine Abstraktion der REST-APIs für Indexvorgänge.

In Azure KI-Suche verfügt ein Vektorindex über ein Indexschema, das Vektor- und Nichtvektorfelder definiert, eine Vektorsuchkonfiguration für Algorithmen, die den Einbettungsraum erstellen, sowie Einstellungen für Vektorfelddefinitionen, die zur Abfragezeit ausgewertet werden. Indizes – Erstellen oder Aktualisieren (REST-API) erstellt den Vektorindex.

Tipp

Voraussetzungen

Konfigurieren des Zugriffs

Bevor Sie beginnen, stellen Sie sicher, dass Sie über Berechtigungen für den Zugriff auf Inhalte und Vorgänge in Azure KI-Suche verfügen. In dieser Schnellstartanleitung werden Microsoft Entra ID für die Authentifizierung und den rollenbasierten Zugriff für die Autorisierung verwendet. Sie müssen ein Besitzer oder Benutzerzugriffsadministrator sein, um Rollen zuzuweisen. Wenn Rollen nicht machbar sind, verwenden Sie stattdessen die schlüsselbasierte Authentifizierung .

So konfigurieren Sie den empfohlenen rollenbasierten Zugriff:

  1. Aktivieren Sie den rollenbasierten Zugriff für Ihren Suchdienst.

  2. Weisen Sie Ihrem Benutzerkonto die folgenden Rollen zu.

    • Suchdienstmitwirkender

    • Datenbeitragender für den Suchindex

    • Suchindexdatenleser

Endpunkt abrufen

Jeder Azure KI-Suche Dienst verfügt über einen endpoint, einer eindeutigen URL, die den Netzwerkzugriff auf den Dienst identifiziert und bereitstellt. In einem späteren Abschnitt geben Sie diesen Endpunkt an, um programmgesteuert eine Verbindung mit Ihrem Suchdienst herzustellen.

So rufen Sie den Endpunkt ab:

  1. Wechseln Sie zum Suchdienst im Azure-Portal.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich den Endpunkt, der wie https://my-service.search.windows.net folgt aussehen wird.

Einrichten der Umgebung

  1. Verwenden Sie Git, um das Beispiel-Repository zu klonen.

    git clone https://github.com/Azure-Samples/azure-search-python-samples
    
  2. Navigieren Sie zum Schnellstartordner, und öffnen Sie ihn in Visual Studio Code.

    cd azure-search-python-samples/Quickstart-Vector-Search
    code .
    
  3. In sample.env ersetzen Sie den Platzhalterwert durch die URL, die Sie im Get-Endpunkt in AZURE_SEARCH_ENDPOINT abgerufen haben.

  4. Umbenennen sample.env in .env.

    mv sample.env .env
    
  5. Öffnen vector-search-quickstart.ipynb.

  6. Drücken Sie STRG+UMSCHALT+P, wählen Sie Notizbuch: Notizbuchkern auswählen, und folgen Sie den Anweisungen, um eine virtuelle Umgebung zu erstellen. Wählen Sie requirements.txt für die Abhängigkeiten aus.

    Nach Abschluss sollte ein .venv Ordner im Projektverzeichnis angezeigt werden.

  7. Melden Sie sich für die schlüssellose Authentifizierung mit Microsoft Entra ID bei Ihrem Azure-Konto an. Wenn Sie über mehrere Abonnements verfügen, wählen Sie das Abonnement aus, das Ihren Azure KI-Suche Dienst enthält.

    az login
    

Ausführen des Codes

  1. Führen Sie die Install packages and set variables Zelle aus, um die erforderlichen Pakete zu installieren und Umgebungsvariablen zu laden.

  2. Führen Sie die verbleibenden Zellen sequenziell aus, um einen Vektorindex zu erstellen, Dokumente hochzuladen und verschiedene Arten von Vektorabfragen auszuführen.

Ausgabe

Jede Codezelle druckt ihre Ausgabe im Notizbuch. Das folgende Beispiel ist die Ausgabe von Single vector search, die Vektorsuchergebnisse nach Ähnlichkeitsbewertung bewertet.

Total results: 7
- HotelId: 48, HotelName: Nordick's Valley Motel, Category: Boutique
- HotelId: 13, HotelName: Luxury Lion Resort, Category: Luxury
- HotelId: 4, HotelName: Sublime Palace Hotel, Category: Boutique
- HotelId: 49, HotelName: Swirling Currents Hotel, Category: Suite
- HotelId: 2, HotelName: Old Century Hotel, Category: Boutique

Grundlegendes zum Code

Hinweis

Möglicherweise wurden die Codeausschnitte in diesem Abschnitt zur Lesbarkeit geändert. Ein vollständiges Arbeitsbeispiel finden Sie im Quellcode.

Nachdem Sie den Code ausgeführt haben, lassen Sie uns die wichtigsten Schritte aufschlüsseln:

  1. Erstellen eines Vektorindexes
  2. Hochladen von Dokumenten in den Index
  3. Abfragen des Indexes

Erstellen eines Vektorindexes

Bevor Sie Inhalte zu Azure KI-Suche hinzufügen, müssen Sie einen Index erstellen, um zu definieren, wie der Inhalt gespeichert und strukturiert wird.

Das Indexschema ist um Hotelinhalte herum organisiert. Beispieldaten bestehen aus Vektor- und Nichtvektorbeschreibungen fiktiver Hotels. Die Create an index Zelle im Notizbuch erstellt das Indexschema, einschließlich des Vektorfelds DescriptionVector.

fields = [
    SimpleField(name="HotelId", type=SearchFieldDataType.String, key=True, filterable=True),
    SearchableField(name="HotelName", type=SearchFieldDataType.String, sortable=True),
    SearchableField(name="Description", type=SearchFieldDataType.String),
    SearchField(
        name="DescriptionVector",
        type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
        searchable=True,
        vector_search_dimensions=1536,
        vector_search_profile_name="my-vector-profile"
    ),
    SearchableField(name="Category", type=SearchFieldDataType.String, sortable=True, filterable=True, facetable=True),
    SearchField(name="Tags", type=SearchFieldDataType.Collection(SearchFieldDataType.String), searchable=True, filterable=True, facetable=True),
    # Additional fields omitted for brevity
]

Wichtige Erkenntnisse:

  • Sie definieren einen Index, indem Sie eine Liste von Feldern erstellen. Jedes Feld wird mit einer Hilfsmethode erstellt, die den Feldtyp und die zugehörigen Einstellungen definiert.

  • Dieser spezielle Index unterstützt mehrere Suchfunktionen:

  • Die vector_search_dimensions Eigenschaft muss mit der Ausgabegröße Ihres Einbettungsmodells übereinstimmen. Diese Schnellstartanleitung verwendet 1.536 Dimensionen, um dem text-embedding-ada-002 Modell zu entsprechen.

  • Die VectorSearch Konfiguration definiert den Algorithmus für ungefähre nächste Nachbarn (ANN). Zu den unterstützten Algorithmen gehören Hierarchical Navigable Small World (HNSW) und exhaustives K-Nearest Neighbor (KNN). Weitere Informationen finden Sie unter Relevanz in der Vektorsuche.

Hochladen von Dokumenten in den Index

Neu erstellte Indizes sind leer. Um einen Index aufzufüllen und durchsuchbar zu machen, müssen Sie JSON-Dokumente hochladen, die dem Indexschema entsprechen.

In Azure KI-Suche dienen Dokumente sowohl als Eingaben für die Indizierung als auch als Ausgaben für Abfragen. Aus Gründen der Einfachheit bietet diese Schnellstartanleitung Beispiel-Hoteldokumente mit vorkompilierten Vektoren. In Produktionsszenarien werden Inhalte häufig aus verbundenen Datenquellen abgerufen und mithilfe von Indexern in JSON transformiert.

Die Create documents payload- und Upload the documents-Zellen laden Dokumente in den Index.

documents = [
    # List of hotel documents with embedded 1536-dimension vectors
    # Each document contains: HotelId, HotelName, Description, DescriptionVector,
    # Category, Tags, ParkingIncluded, LastRenovationDate, Rating, Address, Location
]

search_client = SearchClient(
    endpoint=search_endpoint,
    index_name=index_name,
    credential=credential
)

result = search_client.upload_documents(documents=documents)
for r in result:
    print(f"Key: {r.key}, Succeeded: {r.succeeded}, ErrorMessage: {r.error_message}")

Ihr Code interagiert mit einem bestimmten Suchindex, der in Ihrem Azure KI-Suche-Dienst über das SearchClient gehostet wird, das hauptobjekt, das vom paket azure-search-documents bereitgestellt wird. Der SearchClient Zugriff auf Indexvorgänge bietet, z. B.:

  • Datenaufnahme: upload_documents(), merge_documents()delete_documents()

  • Suchvorgänge: search(), autocomplete()suggest()

Abfragen des Indexes

Die Abfragen im Notizbuch veranschaulichen unterschiedliche Suchmuster. Die Beispielvektorabfragen basieren auf zwei Zeichenfolgen:

  • Volltext-Suchzeichenfolge: "historic hotel walk to restaurants and shopping"

  • Vektorabfragezeichenfolge: "quintessential lodging near running trails, eateries, retail" (in eine mathematische Darstellung vektorisiert)

Die Vektorabfragezeichenfolge ähnelt semantisch der Volltext-Suchzeichenfolge, enthält jedoch Ausdrücke, die nicht im Index vorhanden sind. Eine nur Schlüsselwortsuche nach der Vektorabfragezeichenfolge gibt null Ergebnisse zurück. Die Vektorsuche findet jedoch relevante Übereinstimmungen basierend auf bedeutungsbezogenen und nicht exakten Schlüsselwörtern.

Die folgenden Beispiele beginnen mit einer einfachen Vektorabfrage und fügen nach und nach Filter, Stichwortsuche und semantische Neuranking hinzu.

In der Single vector search Zelle wird ein einfaches Szenario veranschaulicht, in dem Sie Dokumentbeschreibungen finden möchten, die eng mit der Vektorabfragezeichenfolge übereinstimmen. VectorizedQuery konfiguriert die Vektorsuche:

  • k_nearest_neighbors beschränkt, wie viele Ergebnisse basierend auf der Vektorähnlichkeit zurückgegeben werden.
  • fields Gibt das zu durchsuchende Vektorfeld an.
vector_query = VectorizedQuery(
    vector=vector,
    k_nearest_neighbors=5,
    fields="DescriptionVector",
    kind="vector",
    exhaustive=True
)

results = search_client.search(
    vector_queries=[vector_query],
    select=["HotelId", "HotelName", "Description", "Category", "Tags"],
    top=5,
    include_total_count=True
)

Einzelvektorsuche mit einem Filter

In Azure KI-Suche gelten Filter für Nichtvektorfelder in einem Index. Die Single vector search with filter Zelle filtert im Tags Feld, um Hotels herauszufiltern, die kein kostenloses WLAN bereitstellen.

# vector_query omitted for brevity

results = search_client.search(
    vector_queries=[vector_query],
    filter="Tags/any(tag: tag eq 'free wifi')",
    select=["HotelId", "HotelName", "Description", "Category", "Tags"],
    top=7,
    include_total_count=True
)

Einzelvektorsuche mit einem Geofilter

Sie können einen geo-räumlichen Filter angeben, um Die Ergebnisse auf einen bestimmten geografischen Bereich zu beschränken. Die Single vector search with geo filter Zelle gibt einen geografischen Punkt (Washington D.C., mit Längengrad- und Breitengradkoordinaten) an und gibt Hotels innerhalb von 300 Kilometern zurück. Der vector_filter_mode Parameter bestimmt, wann der Filter ausgeführt wird. In diesem Fall führt postFilter den Filter nach der Vektorsuche aus.

# vector_query omitted for brevity

results = search_client.search(
    include_total_count=True,
    top=5,
    select=[
        "HotelId", "HotelName", "Category", "Description", "Address/City", "Address/StateProvince"
    ],
    facets=["Address/StateProvince"],
    filter="geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    vector_filter_mode="postFilter",
    vector_queries=[vector_query]
)

Die Hybridsuche kombiniert Volltext- und Vektorabfragen in einer einzigen Anforderung. Die Hybrid search Zelle führt beide Abfragetypen gleichzeitig aus und verwendet dann reziproke Rangfusion (RRF), um die Ergebnisse in einer einheitlichen Rangfolge zusammenzuführen. RRF verwendet die Umkehrung der Ergebniseinstufungen aus jedem Resultset, um eine zusammengeführte Rangfolge zu erzeugen. Beachten Sie, dass hybride Suchergebnisse einheitlich kleiner als Einzelabfrageergebnisse sind.

# vector_query omitted for brevity

results = search_client.search(
    search_text="historic hotel walk to restaurants and shopping",
    vector_queries=[vector_query],
    select=["HotelId", "HotelName", "Description", "Category", "Tags"],
    top=5,
    include_total_count=True
)

Die Semantic hybrid search Zelle veranschaulicht die semantische Rangfolge, die die Ergebnisse basierend auf dem Sprachverständnis neu ordnet.

# vector_query omitted for brevity

results = search_client.search(
    search_text="historic hotel walk to restaurants and shopping",
    vector_queries=[vector_query],
    select=["HotelId", "HotelName", "Category", "Description"],
    query_type="semantic",
    semantic_configuration_name="my-semantic-config",
    top=5,
    include_total_count=True
)

Vergleichen Sie diese Ergebnisse mit den Hybridsuchergebnissen aus der vorherigen Abfrage. Ohne semantisches Reranking rangiert das Sublime Palace Hotel zuerst, da die reziproke Rangfusion (RRF) die Text- und Vektorergebnisse kombiniert und ein zusammengeführtes Ergebnis erzeugt. Nach semantischem Reranking bewegt sich Swirling Currents Hotel an die Spitze.

Der semantische Rangfolger verwendet Computerverständnismodelle, um auszuwerten, wie gut jedes Ergebnis mit der Absicht der Abfrage übereinstimmt. Die Beschreibung des Swirling Currents Hotels erwähnt "walking access to shopping, dining, entertainment and the city center", die eng mit den Suchabfragen "walk to restaurants and shopping" übereinstimmt. Diese semantische Übereinstimmung für nahegelegene Restaurants und Einkaufsmöglichkeiten stellt es über das Sublime Palace Hotel, im Gegensatz zu dem Sublime Palace Hotel, das in seiner Beschreibung keine begehbaren Annehmlichkeiten hervorhebt.

Wichtige Erkenntnisse:

  • In einer Hybridsuche können Sie die Vektorsuche in die Volltextsuche über Schlüsselwörter integrieren. Filter und semantische Rangfolge gelten nur für Textinhalte, nicht für Vektoren.

  • Tatsächliche Ergebnisse umfassen weitere Details, einschließlich semantischer Beschriftungen und Hervorhebungen. In diesem Schnellstart werden die Ergebnisse zur besseren Lesbarkeit angepasst. Verwenden Sie REST, um die vollständige Struktur der Antwort abzurufen, um die Anforderung auszuführen.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, ist es ratsam, ein Projekt abzuschließen, indem Sie die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterlaufen, können Ihnen Geld kosten.

Wählen Sie im Azure Portal All resources or Resource groups aus dem linken Bereich aus, um Ressourcen zu suchen und zu verwalten. Sie können Ressourcen einzeln löschen oder die Ressourcengruppe löschen, um alle Ressourcen gleichzeitig zu entfernen.

Andernfalls können Sie die Clean up Codezelle ausführen, um den in dieser Schnellstartanleitung erstellten Index zu löschen.

In dieser Schnellstartanleitung verwenden Sie die Azure KI-Suche-Clientbibliothek für JavaScript (kompatibel mit TypeScript), um einen vectorindex zu erstellen, zu laden und abzufragen. Die JavaScript-Clientbibliothek bietet eine Abstraktion über die REST-APIs für Indexvorgänge.

In Azure KI-Suche verfügt ein Vektorindex über ein Indexschema, das Vektor- und Nichtvektorfelder definiert, eine Vektorsuchkonfiguration für Algorithmen, die den Einbettungsraum erstellen, sowie Einstellungen für Vektorfelddefinitionen, die zur Abfragezeit ausgewertet werden. Indizes – Erstellen oder Aktualisieren (REST-API) erstellt den Vektorindex.

Tipp

Voraussetzungen

  • Ein Azure Konto mit einem aktiven Abonnement. Erstellen Sie kostenlos ein Konto.

  • Ein Azure KI-Suche-Dienst. Sie können die Kostenlose Ebene für die meisten dieser Schnellstartanleitungen verwenden, aber wir empfehlen Basic oder höher für größere Datendateien.

  • Node.js 20 LTS oder höher, um den kompilierten Code auszuführen.

  • TypeScript zum Kompilieren von TypeScript in JavaScript.

  • Git um das Beispiel-Repository zu klonen.

  • Die Azure CLI für die schlüssellose Authentifizierung mit Microsoft Entra ID.

Konfigurieren des Zugriffs

Bevor Sie beginnen, stellen Sie sicher, dass Sie über Berechtigungen für den Zugriff auf Inhalte und Vorgänge in Azure KI-Suche verfügen. In dieser Schnellstartanleitung werden Microsoft Entra ID für die Authentifizierung und den rollenbasierten Zugriff für die Autorisierung verwendet. Sie müssen ein Besitzer oder Benutzerzugriffsadministrator sein, um Rollen zuzuweisen. Wenn Rollen nicht machbar sind, verwenden Sie stattdessen die schlüsselbasierte Authentifizierung .

So konfigurieren Sie den empfohlenen rollenbasierten Zugriff:

  1. Aktivieren Sie den rollenbasierten Zugriff für Ihren Suchdienst.

  2. Weisen Sie Ihrem Benutzerkonto die folgenden Rollen zu.

    • Suchdienstmitwirkender

    • Datenbeitragender für den Suchindex

    • Suchindexdatenleser

Endpunkt abrufen

Jeder Azure KI-Suche Dienst verfügt über einen endpoint, einer eindeutigen URL, die den Netzwerkzugriff auf den Dienst identifiziert und bereitstellt. In einem späteren Abschnitt geben Sie diesen Endpunkt an, um programmgesteuert eine Verbindung mit Ihrem Suchdienst herzustellen.

So rufen Sie den Endpunkt ab:

  1. Wechseln Sie zum Suchdienst im Azure-Portal.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich den Endpunkt, der wie https://my-service.search.windows.net folgt aussehen wird.

Einrichten der Umgebung

  1. Verwenden Sie Git, um das Beispiel-Repository zu klonen.

    git clone https://github.com/Azure-Samples/azure-search-javascript-samples
    
  2. Navigieren Sie zum Schnellstartordner.

    cd azure-search-javascript-samples/quickstart-vector-ts
    
  3. In sample.env ersetzen Sie den Platzhalterwert durch die URL, die Sie im Get-Endpunkt in AZURE_SEARCH_ENDPOINT abgerufen haben.

  4. Umbenennen sample.env in .env.

    mv sample.env .env
    
  5. Installieren Sie die Abhängigkeiten.

    npm install
    

    Nach Abschluss der Installation sollte ein node_modules Ordner im Projektverzeichnis angezeigt werden.

  6. Kompilieren Sie die TypeScript-Dateien in JavaScript.

    npm run build
    
  7. Melden Sie sich für die schlüssellose Authentifizierung mit Microsoft Entra ID bei Ihrem Azure-Konto an. Wenn Sie über mehrere Abonnements verfügen, wählen Sie das Abonnement aus, das Ihren Azure KI-Suche Dienst enthält.

    az login
    

Ausführen des Codes

  1. Erstellen Sie einen Vektorindex.

    node -r dotenv/config dist/createIndex.js
    
  2. Laden Sie Dokumente, die vorkompilierte Einbettungen enthalten.

    node -r dotenv/config dist/uploadDocuments.js
    
  3. Führen Sie eine Vektorsuchabfrage aus.

    node -r dotenv/config dist/searchSingle.js
    
  4. (Optional) Führen Sie zusätzliche Abfragevariationen aus.

    node -r dotenv/config dist/searchSingleWithFilter.js
    node -r dotenv/config dist/searchSingleWithFilterGeo.js
    node -r dotenv/config dist/searchHybrid.js
    node -r dotenv/config dist/searchSemanticHybrid.js
    

    Hinweis

    Diese Befehle führen die kompilierten .js Dateien aus dem dist Ordner aus. TypeScript-Code muss in JavaScript transpiliert werden, bevor Node.js es ausführen kann, weshalb Sie zuvor ausgeführt haben npm run build.

Ausgabe

Die Ausgabe von createIndex.ts zeigt den Indexnamen und die Bestätigung an.

Using Azure Search endpoint: https://<search-service-name>.search.windows.net
Using index name: hotels-vector-quickstart
Creating index...
hotels-vector-quickstart created

Die Ausgabe von uploadDocuments.ts zeigt den Erfolgsstatus für jedes indizierte Dokument.

Uploading documents...
Key: 1, Succeeded: true, ErrorMessage: none
Key: 2, Succeeded: true, ErrorMessage: none
Key: 3, Succeeded: true, ErrorMessage: none
Key: 4, Succeeded: true, ErrorMessage: none
Key: 48, Succeeded: true, ErrorMessage: none
Key: 49, Succeeded: true, ErrorMessage: none
Key: 13, Succeeded: true, ErrorMessage: none
All documents indexed successfully.

Die Ausgabe von searchSingle.ts zeigt Vektorsuchergebnisse, die nach Ähnlichkeitswert bewertet sind.

Single Vector search found 5
- HotelId: 48, HotelName: Nordick's Valley Motel, Tags: ["continental breakfast","air conditioning","free wifi"], Score 0.6605852
- HotelId: 13, HotelName: Luxury Lion Resort, Tags: ["bar","concierge","restaurant"], Score 0.6333684
- HotelId: 4, HotelName: Sublime Palace Hotel, Tags: ["concierge","view","air conditioning"], Score 0.605672
- HotelId: 49, HotelName: Swirling Currents Hotel, Tags: ["air conditioning","laundry service","24-hour front desk service"], Score 0.6026341
- HotelId: 2, HotelName: Old Century Hotel, Tags: ["pool","free wifi","air conditioning","concierge"], Score 0.57902366

Grundlegendes zum Code

Hinweis

Möglicherweise wurden die Codeausschnitte in diesem Abschnitt zur Lesbarkeit geändert. Ein vollständiges Arbeitsbeispiel finden Sie im Quellcode.

Nachdem Sie den Code ausgeführt haben, lassen Sie uns die wichtigsten Schritte aufschlüsseln:

  1. Erstellen eines Vektorindexes
  2. Hochladen von Dokumenten in den Index
  3. Abfragen des Indexes

Erstellen eines Vektorindexes

Bevor Sie Inhalte zu Azure KI-Suche hinzufügen, müssen Sie einen Index erstellen, um zu definieren, wie der Inhalt gespeichert und strukturiert wird.

Das Indexschema ist um Hotelinhalte herum organisiert. Beispieldaten bestehen aus Vektor- und Nichtvektorbeschreibungen fiktiver Hotels. Der folgende Code in createIndex.ts erstellt das Indexschema, einschließlich des Vektorfelds DescriptionVector.

const searchFields: SearchField[] = [
    { name: "HotelId", type: "Edm.String", key: true, sortable: true, filterable: true, facetable: true },
    { name: "HotelName", type: "Edm.String", searchable: true, filterable: true },
    { name: "Description", type: "Edm.String", searchable: true },
    {
        name: "DescriptionVector",
        type: "Collection(Edm.Single)",
        searchable: true,
        vectorSearchDimensions: 1536,
        vectorSearchProfileName: "vector-profile"
    },
    { name: "Category", type: "Edm.String", filterable: true, facetable: true },
    { name: "Tags", type: "Collection(Edm.String)", filterable: true },
    // Additional fields: ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const vectorSearch: VectorSearch = {
    profiles: [
        {
            name: "vector-profile",
            algorithmConfigurationName: "vector-search-algorithm"
        }
    ],
    algorithms: [
        {
            name: "vector-search-algorithm",
            kind: "hnsw",
            parameters: { m: 4, efConstruction: 400, efSearch: 1000, metric: "cosine" }
        }
    ]
};

const semanticSearch: SemanticSearch = {
    configurations: [
        {
            name: "semantic-config",
            prioritizedFields: {
                contentFields: [{ name: "Description" }],
                keywordsFields: [{ name: "Category" }],
                titleField: { name: "HotelName" }
            }
        }
    ]
};

const searchIndex: SearchIndex = {
    name: indexName,
    fields: searchFields,
    vectorSearch: vectorSearch,
    semanticSearch: semanticSearch,
    suggesters: [{ name: "sg", searchMode: "analyzingInfixMatching", sourceFields: ["HotelName"] }]
};

const result = await indexClient.createOrUpdateIndex(searchIndex);

Wichtige Erkenntnisse:

  • Sie definieren einen Index, indem Sie eine Liste von Feldern erstellen.

  • Dieser spezielle Index unterstützt mehrere Suchfunktionen:

  • Die vectorSearchDimensions Eigenschaft muss mit der Ausgabegröße Ihres Einbettungsmodells übereinstimmen. Diese Schnellstartanleitung verwendet 1.536 Dimensionen, um dem text-embedding-ada-002 Modell zu entsprechen.

  • Die vectorSearch Konfiguration definiert den Algorithmus für ungefähre nächste Nachbarn (ANN). Zu den unterstützten Algorithmen gehören Hierarchical Navigable Small World (HNSW) und exhaustives K-Nearest Neighbor (KNN). Weitere Informationen finden Sie unter Relevanz in der Vektorsuche.

Hochladen von Dokumenten in den Index

Neu erstellte Indizes sind leer. Um einen Index aufzufüllen und durchsuchbar zu machen, müssen Sie JSON-Dokumente hochladen, die dem Indexschema entsprechen.

In Azure KI-Suche dienen Dokumente sowohl als Eingaben für die Indizierung als auch als Ausgaben für Abfragen. Aus Gründen der Einfachheit bietet diese Schnellstartanleitung Beispiel-Hoteldokumente mit vorkompilierten Vektoren. In Produktionsszenarien werden Inhalte häufig aus verbundenen Datenquellen abgerufen und mithilfe von Indexern in JSON transformiert.

Der folgende Code in uploadDocuments.ts lädt Dokumente in Ihren Suchdienst hoch.

const DOCUMENTS = [
    // Array of hotel documents with embedded 1536-dimension vectors
    // Each document contains: HotelId, HotelName, Description, DescriptionVector,
    // Category, Tags, ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const searchClient = new SearchClient(searchEndpoint, indexName, credential);

const result = await searchClient.uploadDocuments(DOCUMENTS);
for (const r of result.results) {
    console.log(`Key: ${r.key}, Succeeded: ${r.succeeded}`);
}

Ihr Code interagiert mit einem bestimmten Suchindex, der in Ihrem Azure KI-Suche-Dienst über das SearchClient gehostet wird, das hauptobjekt, das vom paket @azure/search-documents bereitgestellt wird. Der SearchClient Zugriff auf Indexvorgänge bietet, z. B.:

  • Datenaufnahme: uploadDocuments, mergeDocumentsdeleteDocuments

  • Suchvorgänge: search, autocompletesuggest

Abfragen des Indexes

Die Abfragen in den Suchdateien veranschaulichen unterschiedliche Suchmuster. Die Beispielvektorabfragen basieren auf zwei Zeichenfolgen:

  • Volltext-Suchzeichenfolge: "historic hotel walk to restaurants and shopping"

  • Vektorabfragezeichenfolge: "quintessential lodging near running trails, eateries, retail" (in eine mathematische Darstellung vektorisiert)

Die Vektorabfragezeichenfolge ähnelt semantisch der Volltext-Suchzeichenfolge, enthält jedoch Ausdrücke, die nicht im Index vorhanden sind. Eine nur Schlüsselwortsuche nach der Vektorabfragezeichenfolge gibt null Ergebnisse zurück. Die Vektorsuche findet jedoch relevante Übereinstimmungen basierend auf bedeutungsbezogenen und nicht exakten Schlüsselwörtern.

Die folgenden Beispiele beginnen mit einer einfachen Vektorabfrage und fügen nach und nach Filter, Stichwortsuche und semantische Neuranking hinzu.

searchSingle.ts veranschaulicht ein einfaches Szenario, in dem Sie Dokumentbeschreibungen finden möchten, die eng mit der Vektorabfragezeichenfolge übereinstimmen. Das VectorQuery Objekt konfiguriert die Vektorsuche:

  • kNearestNeighborsCount beschränkt, wie viele Ergebnisse basierend auf der Vektorähnlichkeit zurückgegeben werden.
  • fields Gibt das zu durchsuchende Vektorfeld an.
const vectorQuery: VectorQuery<HotelDocument> = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions: SearchOptions<HotelDocument> = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"] as const,
    includeTotalCount: true,
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results: SearchDocumentsResult<HotelDocument> = await searchClient.search("*", searchOptions);

for await (const result of results.results) {
    const doc = result.document;
    console.log(`HotelId: ${doc.HotelId}, HotelName: ${doc.HotelName}, Score: ${result.score}`);
}

Einzelvektorsuche mit einem Filter

In Azure KI-Suche gelten Filter für Nichtvektorfelder in einem Index. searchSingleWithFilter.ts filtert auf dem Tags Feld, um Hotels herauszufiltern, die kein kostenloses WLAN bieten.

const searchOptions: SearchOptions<HotelDocument> = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"] as const,
    includeTotalCount: true,
    filter: "Tags/any(tag: tag eq 'free wifi')", // Adding filter for "free wifi" tag
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results: SearchDocumentsResult<HotelDocument> = await searchClient.search("*", searchOptions);

Einzelvektorsuche mit einem Geofilter

Sie können einen geo-räumlichen Filter angeben, um Die Ergebnisse auf einen bestimmten geografischen Bereich zu beschränken. searchSingleWithGeoFilter.ts Gibt einen geografischen Punkt (Washington D.C., mit Längen- und Breitengradkoordinaten) an und gibt Hotels innerhalb von 300 Kilometern zurück. Die filterMode Eigenschaft bestimmt, wann der Filter ausgeführt wird. In diesem Fall führt postFilter den Filter nach der Vektorsuche aus.

const searchOptions: SearchOptions<HotelDocument> = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description", "Address/City", "Address/StateProvince"] as const,
    facets: ["Address/StateProvince"],
    filter: "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

Die Hybridsuche kombiniert Volltext- und Vektorabfragen in einer einzigen Anforderung. searchHybrid.ts führt beide Abfragetypen gleichzeitig aus und verwendet dann reziprozien Rangfusion (RRF), um die Ergebnisse in einer einheitlichen Rangfolge zusammenzuführen. RRF verwendet die Umkehrung der Ergebniseinstufungen aus jedem Resultset, um eine zusammengeführte Rangfolge zu erzeugen. Beachten Sie, dass hybride Suchergebnisse einheitlich kleiner als Einzelabfrageergebnisse sind.

const vectorQuery: VectorQuery<HotelDocument> = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions: SearchOptions<HotelDocument> = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"] as const,
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

// Use search text for keyword search (hybrid search = vector + keyword)
const searchText = "historic hotel walk to restaurants and shopping";
const results: SearchDocumentsResult<HotelDocument> = await searchClient.search(searchText, searchOptions);

searchSemanticHybrid.ts veranschaulicht die semantische Rangfolge, die Ergebnisse basierend auf dem Sprachverständnis neu anordnet.

const searchOptions: SearchOptions<HotelDocument> = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description"] as const,
    queryType: "semantic" as const,
    semanticSearchOptions: {
        configurationName: "semantic-config"
    },
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const searchText = "historic hotel walk to restaurants and shopping";
const results: SearchDocumentsResult<HotelDocument> = await searchClient.search(searchText, searchOptions);

for await (const result of results.results) {
    console.log(`Score: ${result.score}, Re-ranker Score: ${result.rerankerScore}`);
}

Vergleichen Sie diese Ergebnisse mit den Hybridsuchergebnissen aus der vorherigen Abfrage. Ohne semantisches Reranking rangiert das Sublime Palace Hotel zuerst, da die reziproke Rangfusion (RRF) die Text- und Vektorergebnisse kombiniert und ein zusammengeführtes Ergebnis erzeugt. Nach semantischem Reranking bewegt sich Swirling Currents Hotel an die Spitze.

Der semantische Rangfolger verwendet Computerverständnismodelle, um auszuwerten, wie gut jedes Ergebnis mit der Absicht der Abfrage übereinstimmt. Die Beschreibung des Swirling Currents Hotels erwähnt "walking access to shopping, dining, entertainment and the city center", die eng mit den Suchabfragen "walk to restaurants and shopping" übereinstimmt. Diese semantische Übereinstimmung für nahegelegene Restaurants und Einkaufsmöglichkeiten stellt es über das Sublime Palace Hotel, im Gegensatz zu dem Sublime Palace Hotel, das in seiner Beschreibung keine begehbaren Annehmlichkeiten hervorhebt.

Wichtige Erkenntnisse:

  • In einer Hybridsuche können Sie die Vektorsuche in die Volltextsuche über Schlüsselwörter integrieren. Filter und semantische Rangfolge gelten nur für Textinhalte, nicht für Vektoren.

  • Tatsächliche Ergebnisse umfassen weitere Details, einschließlich semantischer Beschriftungen und Hervorhebungen. In diesem Schnellstart werden die Ergebnisse zur besseren Lesbarkeit angepasst. Verwenden Sie REST, um die vollständige Struktur der Antwort abzurufen, um die Anforderung auszuführen.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, ist es ratsam, ein Projekt abzuschließen, indem Sie die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterlaufen, können Ihnen Geld kosten.

Wählen Sie im Azure Portal All resources or Resource groups aus dem linken Bereich aus, um Ressourcen zu suchen und zu verwalten. Sie können Ressourcen einzeln löschen oder die Ressourcengruppe löschen, um alle Ressourcen gleichzeitig zu entfernen.

Führen Sie andernfalls den folgenden Befehl aus, um den in dieser Schnellstartanleitung erstellten Index zu löschen.

npm run build && node -r dotenv/config dist/deleteIndex.js

In dieser Schnellstartanleitung verwenden Sie die Azure KI-Suche REST-APIs zum Erstellen, Laden und Abfragen eines vectorindex.

In Azure KI-Suche verfügt ein Vektorindex über ein Indexschema, das Vektor- und Nichtvektorfelder definiert, eine Vektorsuchkonfiguration für Algorithmen, die den Einbettungsraum erstellen, sowie Einstellungen für Vektorfelddefinitionen, die zur Abfragezeit ausgewertet werden. Indizes – Erstellen oder Aktualisieren (REST-API) erstellt den Vektorindex.

Tipp

Voraussetzungen

Konfigurieren des Zugriffs

Bevor Sie beginnen, stellen Sie sicher, dass Sie über Berechtigungen für den Zugriff auf Inhalte und Vorgänge in Azure KI-Suche verfügen. In dieser Schnellstartanleitung werden Microsoft Entra ID für die Authentifizierung und den rollenbasierten Zugriff für die Autorisierung verwendet. Sie müssen ein Besitzer oder Benutzerzugriffsadministrator sein, um Rollen zuzuweisen. Wenn Rollen nicht machbar sind, verwenden Sie stattdessen die schlüsselbasierte Authentifizierung .

So konfigurieren Sie den empfohlenen rollenbasierten Zugriff:

  1. Aktivieren Sie den rollenbasierten Zugriff für Ihren Suchdienst.

  2. Weisen Sie Ihrem Benutzerkonto die folgenden Rollen zu.

    • Suchdienstmitwirkender

    • Datenbeitragender für den Suchindex

    • Suchindexdatenleser

Endpunkt abrufen

Jeder Azure KI-Suche Dienst verfügt über einen endpoint, einer eindeutigen URL, die den Netzwerkzugriff auf den Dienst identifiziert und bereitstellt. In einem späteren Abschnitt geben Sie diesen Endpunkt an, um programmgesteuert eine Verbindung mit Ihrem Suchdienst herzustellen.

So rufen Sie den Endpunkt ab:

  1. Wechseln Sie zum Suchdienst im Azure-Portal.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich den Endpunkt, der wie https://my-service.search.windows.net folgt aussehen wird.

Einrichten der Umgebung

  1. Verwenden Sie Git, um das Beispiel-Repository zu klonen.

    git clone https://github.com/Azure-Samples/azure-search-rest-samples
    
  2. Navigieren Sie zum Schnellstartordner, und öffnen Sie ihn in Visual Studio Code.

    cd azure-search-rest-samples/Quickstart-vectors
    code .
    
  3. In az-search-quickstart-vectors.rest ersetzen Sie den Platzhalterwert durch die URL, die Sie im Get-Endpunkt in @baseUrl abgerufen haben.

  4. Melden Sie sich für die schlüssellose Authentifizierung mit Microsoft Entra ID bei Ihrem Azure-Konto an. Wenn Sie über mehrere Abonnements verfügen, wählen Sie das Abonnement aus, das Ihren Azure KI-Suche Dienst enthält.

    az login
    
  5. Generieren Sie für die schlüssellose Authentifizierung mit Microsoft Entra ID ein Zugriffstoken.

    az account get-access-token --scope https://search.azure.com/.default --query accessToken -o tsv
    
  6. Ersetzen Sie den Platzhalterwert @token durch das Token aus dem vorherigen Schritt.

Ausführen des Codes

  1. Wählen Sie unter ### List existing indexes by name"Senden" die Option " Anfrage senden " aus, um Ihre Verbindung zu überprüfen.

    Eine Antwort sollte in einem angrenzenden Bereich angezeigt werden. Wenn Sie über vorhandene Indizes verfügen, werden sie aufgelistet. Andernfalls ist die Liste leer. Wenn der HTTP-Code lautet 200 OK, können Sie fortfahren.

  2. Senden Sie die verbleibenden Anforderungen sequenziell, um einen Vektorindex zu erstellen, Dokumente hochzuladen und verschiedene Arten von Vektorabfragen auszuführen.

Ausgabe

Jede Abfrageanforderung gibt JSON-Ergebnisse zurück. Das folgende Beispiel zeigt die Ausgabe der ### Run a single vector query Anfrage, die Vektorsuchergebnisse nach Ähnlichkeitswerten sortiert darstellt.

{
  "@odata.count": 5,
  "value": [
    {
      "@search.score": 0.6605852,
      "HotelId": "48",
      "HotelName": "Nordick's Valley Motel",
      "Description": "Only 90 miles (about 2 hours) from the nation's capital and nearby most everything the historic valley has to offer. Hiking? Wine Tasting? Exploring the caverns? It's all nearby and we have specially priced packages to help make our B&B your home base for fun while visiting the valley.",
      "Category": "Boutique",
      "Tags": [
        "continental breakfast",
        "air conditioning",
        "free wifi"
      ]
    },
    {
      "@search.score": 0.6333684,
      "HotelId": "13",
      "HotelName": "Luxury Lion Resort",
      "Description": "Unmatched Luxury. Visit our downtown hotel to indulge in luxury accommodations. Moments from the stadium and transportation hubs, we feature the best in convenience and comfort.",
      "Category": "Luxury",
      "Tags": [
        "bar",
        "concierge",
        "restaurant"
      ]
    },
    {
      "@search.score": 0.605672,
      "HotelId": "4",
      "HotelName": "Sublime Palace Hotel",
      "Description": "Sublime Palace Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 19th century resort, updated for every modern convenience.",
      "Category": "Boutique",
      "Tags": [
        "concierge",
        "view",
        "air conditioning"
      ]
    },
    {
      "@search.score": 0.6026341,
      "HotelId": "49",
      "HotelName": "Swirling Currents Hotel",
      "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center. Each room comes equipped with a microwave, a coffee maker and a minifridge. In-room entertainment includes complimentary W-Fi and flat-screen TVs.",
      "Category": "Suite",
      "Tags": [
        "air conditioning",
        "laundry service",
        "24-hour front desk service"
      ]
    },
    {
      "@search.score": 0.57902366,
      "HotelId": "2",
      "HotelName": "Old Century Hotel",
      "Description": "The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts. The hotel also regularly hosts events like wine tastings, beer dinners, and live music.",
      "Category": "Boutique",
      "Tags": [
        "pool",
        "free wifi",
        "air conditioning",
        "concierge"
      ]
    }
  ]
}

Grundlegendes zum Code

Hinweis

Möglicherweise wurden die Codeausschnitte in diesem Abschnitt zur Lesbarkeit geändert. Ein vollständiges Arbeitsbeispiel finden Sie im Quellcode.

Nachdem Sie den Code ausgeführt haben, lassen Sie uns die wichtigsten Schritte aufschlüsseln:

  1. Erstellen eines Vektorindexes
  2. Hochladen von Dokumenten in den Index
  3. Abfragen des Indexes

Erstellen eines Vektorindexes

Bevor Sie Inhalte zu Azure KI-Suche hinzufügen, müssen Sie einen Index erstellen, um zu definieren, wie der Inhalt gespeichert und strukturiert wird. In dieser Schnellstartanleitung werden Indizes – Erstellen (REST-API) aufgerufen, um einen Vektorindex mit dem Namen hotels-vector-quickstart und seinen physischen Datenstrukturen in Ihrem Suchdienst zu erstellen.

Das Indexschema ist um Hotelinhalte herum organisiert. Beispieldaten bestehen aus Vektor- und Nichtvektorbeschreibungen fiktiver Hotels. Der folgende Auszug zeigt die Schlüsselstruktur der ### Create a new index Anforderung.

PUT {{baseUrl}}/indexes/hotels-vector-quickstart?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "name": "hotels-vector-quickstart",
    "fields": [
        { "name": "HotelId", "type": "Edm.String", "key": true, "filterable": true },
        { "name": "HotelName", "type": "Edm.String", "searchable": true },
        { "name": "Description", "type": "Edm.String", "searchable": true },
        {
            "name": "DescriptionVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "dimensions": 1536,
            "vectorSearchProfile": "my-vector-profile"
        },
        { "name": "Category", "type": "Edm.String", "filterable": true, "facetable": true },
        { "name": "Tags", "type": "Collection(Edm.String)", "filterable": true, "facetable": true }
        // Additional fields omitted for brevity
    ],
    "vectorSearch": {
        "algorithms": [
            { "name": "hnsw-vector-config", "kind": "hnsw" }
        ],
        "profiles": [
            { "name": "my-vector-profile", "algorithm": "hnsw-vector-config" }
        ]
    },
    "semantic": {
        "configurations": [
            {
                "name": "semantic-config",
                "prioritizedFields": {
                    "titleField": { "fieldName": "HotelName" },
                    "prioritizedContentFields": [{ "fieldName": "Description" }]
                }
            }
        ]
    }
}

Wichtige Erkenntnisse:

  • Dieser spezielle Index unterstützt mehrere Suchfunktionen:

  • Die dimensions Eigenschaft muss mit der Ausgabegröße Ihres Einbettungsmodells übereinstimmen. Diese Schnellstartanleitung verwendet 1.536 Dimensionen, um dem text-embedding-ada-002 Modell zu entsprechen.

  • Der Abschnitt definiert den Algorithmus für näherste Nachbarn (ANN).The vectorSearch section defines the Approximate Nearest Neighbor (ANN) algorithm. Zu den unterstützten Algorithmen gehören Hierarchical Navigable Small World (HNSW) und exhaustives K-Nearest Neighbor (KNN). Weitere Informationen finden Sie unter Relevanz in der Vektorsuche.

Hochladen von Dokumenten in den Index

Neu erstellte Indizes sind leer. Um einen Index aufzufüllen und durchsuchbar zu machen, müssen Sie JSON-Dokumente hochladen, die dem Indexschema entsprechen.

In Azure KI-Suche dienen Dokumente sowohl als Eingaben für die Indizierung als auch als Ausgaben für Abfragen. Aus Gründen der Einfachheit stellt diese Schnellstartanleitung Beispiel-Hoteldokumente als Inline-JSON bereit. In Produktionsszenarien werden Inhalte jedoch häufig aus verbundenen Datenquellen abgerufen und mithilfe von Indexern in JSON transformiert.

Diese Schnellstartanleitung ruft Dokumente – Index (REST-API) auf, um Ihrem Index Beispiel-Hoteldokumente hinzuzufügen. Der folgende Auszug zeigt die Struktur der ### Upload 7 documents Anforderung.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/index?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "value": [
        {
            "@search.action": "mergeOrUpload",
            "HotelId": "1",
            "HotelName": "Stay-Kay City Hotel",
            "Description": "This classic hotel is ideally located on the main commercial artery of the city...",
            "DescriptionVector": [-0.0347, 0.0289, ... ],  // 1536 floats
            "Category": "Boutique",
            "Tags": ["view", "air conditioning", "concierge"],
            "ParkingIncluded": false,
            "Rating": 3.60,
            "Address": { "City": "New York", "StateProvince": "NY" },
            "Location": { "type": "Point", "coordinates": [-73.975403, 40.760586] }
        }
        // Additional documents omitted for brevity
    ]
}

Wichtige Erkenntnisse:

  • Jedes Dokument im value Array stellt ein Hotel dar und enthält Felder, die dem Indexschema entsprechen. Der @search.action Parameter gibt den Vorgang an, der für jedes Dokument ausgeführt werden soll. In diesem Schnellstart wird mergeOrUpload verwendet, um das Dokument hinzuzufügen, wenn es nicht vorhanden ist, oder es zu aktualisieren, falls es vorhanden ist.

  • Dokumente in der Nutzlast bestehen aus Feldern, die im Indexschema definiert sind.

Abfragen des Indexes

Die Abfragen in der Beispieldatei veranschaulichen unterschiedliche Suchmuster. Die Beispielvektorabfragen basieren auf zwei Zeichenfolgen:

  • Volltext-Suchzeichenfolge: "historic hotel walk to restaurants and shopping"

  • Vektorabfragezeichenfolge: "quintessential lodging near running trails, eateries, retail" (in eine mathematische Darstellung vektorisiert)

Die Vektorabfragezeichenfolge ähnelt semantisch der Volltext-Suchzeichenfolge, enthält jedoch Ausdrücke, die nicht im Index vorhanden sind. Eine nur Schlüsselwortsuche nach der Vektorabfragezeichenfolge gibt null Ergebnisse zurück. Die Vektorsuche findet jedoch relevante Übereinstimmungen basierend auf bedeutungsbezogenen und nicht exakten Schlüsselwörtern.

Die folgenden Beispiele beginnen mit einer einfachen Vektorabfrage und fügen nach und nach Filter, Stichwortsuche und semantische Neuranking hinzu.

Die ### Run a single vector query Anforderung veranschaulicht ein einfaches Szenario, in dem Sie Dokumentbeschreibungen finden möchten, die eng mit der Vektorabfragezeichenfolge übereinstimmen. Das vectorQueries Array konfiguriert die Vektorsuche:

  • k beschränkt, wie viele Ergebnisse basierend auf der Vektorähnlichkeit zurückgegeben werden.
  • fields Gibt das zu durchsuchende Vektorfeld an.
POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "select": "HotelId, HotelName, Description, Category, Tags",
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector of "quintessential lodging near running trails, eateries, retail"
            "k": 5,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Einzelvektorsuche mit einem Filter

In Azure KI-Suche gelten Filter für Nichtvektorfelder in einem Index. Die ### Run a vector query with a filter Anforderung filtert im Tags Feld, um Hotels herauszufiltern, die kein kostenloses WLAN bereitstellen.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "select": "HotelId, HotelName, Description, Category, Tags",
    "filter": "Tags/any(tag: tag eq 'free wifi')",
    "vectorFilterMode": "postFilter",
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 7,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Einzelvektorsuche mit einem Geofilter

Sie können einen geo-räumlichen Filter angeben, um Die Ergebnisse auf einen bestimmten geografischen Bereich zu beschränken. Die ### Run a vector query with a geo filter Anforderung gibt einen geografischen Punkt (Washington D.C., mit Längengrad- und Breitenkoordinaten) an und gibt Hotels innerhalb von 300 Kilometern zurück. Der vectorFilterMode Parameter bestimmt, wann der Filter ausgeführt wird. In diesem Fall führt postFilter den Filter nach der Vektorsuche aus.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "select": "HotelId, HotelName, Address/City, Address/StateProvince, Description",
    "filter": "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    "vectorFilterMode": "postFilter",
    "top": 5,
    "facets": [ "Address/StateProvince"],
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 5,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Die Hybridsuche kombiniert Volltext- und Vektorabfragen in einer einzigen Anforderung. Die ### Run a hybrid query Anforderung führt beide Abfragetypen gleichzeitig aus und verwendet dann reziproke Rangfusion (RRF), um die Ergebnisse in einer einheitlichen Rangfolge zusammenzuführen. RRF verwendet die Umkehrung der Ergebniseinstufungen aus jedem Resultset, um eine zusammengeführte Rangfolge zu erzeugen. Beachten Sie, dass hybride Suchergebnisse einheitlich kleiner als Einzelabfrageergebnisse sind.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "top": 5,
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 5,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Die ### Run a hybrid query with semantic reranking Anfrage veranschaulicht die semantische Rangfolge, die Ergebnisse basierend auf dem Sprachverständnis neu anordnet.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelId, HotelName, Category, Description",
    "queryType": "semantic",
    "semanticConfiguration": "semantic-config",
    "top": 5,
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 7,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Vergleichen Sie diese Ergebnisse mit den Hybridsuchergebnissen aus der vorherigen Abfrage. Ohne semantisches Reranking rangiert das Sublime Palace Hotel zuerst, da die reziproke Rangfusion (RRF) die Text- und Vektorergebnisse kombiniert und ein zusammengeführtes Ergebnis erzeugt. Nach semantischem Reranking bewegt sich Swirling Currents Hotel an die Spitze.

Der semantische Rangfolger verwendet Computerverständnismodelle, um auszuwerten, wie gut jedes Ergebnis mit der Absicht der Abfrage übereinstimmt. Die Beschreibung des Swirling Currents Hotels erwähnt "walking access to shopping, dining, entertainment and the city center", die eng mit den Suchabfragen "walk to restaurants and shopping" übereinstimmt. Diese semantische Übereinstimmung für nahegelegene Restaurants und Einkaufsmöglichkeiten stellt es über das Sublime Palace Hotel, im Gegensatz zu dem Sublime Palace Hotel, das in seiner Beschreibung keine begehbaren Annehmlichkeiten hervorhebt.

Wichtige Erkenntnisse:

  • In einer Hybridsuche können Sie die Vektorsuche in die Volltextsuche über Schlüsselwörter integrieren. Filter und semantische Rangfolge gelten nur für Textinhalte, nicht für Vektoren.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, ist es ratsam, ein Projekt abzuschließen, indem Sie die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterlaufen, können Ihnen Geld kosten.

Wählen Sie im Azure Portal All resources or Resource groups aus dem linken Bereich aus, um Ressourcen zu suchen und zu verwalten. Sie können Ressourcen einzeln löschen oder die Ressourcengruppe löschen, um alle Ressourcen gleichzeitig zu entfernen.

Andernfalls können Sie die Anforderung senden, um den ### Delete an index in dieser Schnellstartanleitung erstellten Index zu löschen.