次の方法で共有


クイック スタート: ベクター検索

このクイック スタートでは、.NET 用の Azure AI 検索 クライアント ライブラリを使用して、vector インデックスを作成、読み込み、クエリします。 .NET クライアント ライブラリは、インデックス操作用の REST API に対する抽象化を提供します。

Azure AI 検索では、ベクター インデックスには、ベクター フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクター検索構成、およびクエリ時に評価されるベクター フィールド定義の設定があります。 インデックス - 作成または更新 (REST API) によってベクター インデックスが作成されます。

ヒント

  • すぐに始めたいですか? GitHubにsource コードをダウンロードします。
  • このクイック スタートでは、ベクター化の手順を省略し、インライン埋め込みを提供します。 独自のコンテンツ に対する統合ベクター化 の場合は、 データのインポート (新しい) ウィザードを試してください。

前提条件

  • アクティブなサブスクリプションを持つAzure アカウント。 無料でアカウントを作成できます。

  • Azure AI 検索 サービス。 このクイック スタートのほとんどは Free レベルを使用できますが、より大きなデータ ファイルには Basic 以上をお勧めします。

  • オプションのセマンティック ハイブリッド クエリに対して検索サービスで有効になっているセマンティック ランカー。

  • .NET 8 以降。

  • Visual Studio Code

  • Git を使ってサンプルリポジトリを複製します。

  • Microsoft Entra IDを使用したキーレス認証のAzure CLI

アクセスを構成する

開始する前に、Azure AI 検索のコンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 このクイック スタートでは、認証にMicrosoft Entra IDを使用し、承認にはロールベースのアクセスを使用します。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールの使用が困難な場合は、代わりにキー ベースの認証を使用してください。

推奨されるロールベースのアクセスを構成するには:

  1. 検索サービスのロールベースのアクセスを有効にします。

  2. ユーザー アカウントに次のロールを割り当てます 。

    • Search Service サービス貢献者

    • 検索インデックス データ共同作成者

    • 検索インデックス データ閲覧者

エンドポイントを取得する

各Azure AI 検索 サービスには endpoint があります。これは、サービスを識別してネットワーク アクセスを提供する一意の URL です。 後のセクションでは、このエンドポイントを指定して、プログラムで検索サービスに接続します。

エンドポイントを取得するには:

  1. Azure ポータルにサインインし、検索サービスを選択します。

  2. 左側のウィンドウで、[ 概要] を選択します。

  3. のような形式のエンドポイントをメモしておいてください。

環境をセットアップする

  1. Git を使用してサンプル リポジトリを複製します。

    git clone https://github.com/Azure-Samples/azure-search-dotnet-samples
    
  2. クイック スタート フォルダーに移動し、Visual Studio Codeで開きます。

    cd azure-search-dotnet-samples/quickstart-vector-search
    code .
    
  3. で、のプレースホルダー値を Get エンドポイントで取得した URL に置き換えます。

  4. に対して前の手順を繰り返します。

  5. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索 サービスを含むサブスクリプションを選択します。

    az login
    

コードの実行

  1. 最初のプロジェクトを実行して、インデックスを作成して設定します。

    cd VectorSearchCreatePopulateIndex
    dotnet run
    
  2. で、実行するクエリ メソッドのコメントを解除します。

  3. 2 番目のプロジェクトを実行して、インデックスに対してこれらのクエリを実行します。

    cd ..\VectorSearchExamples
    dotnet run
    

アウトプット

最初のプロジェクトの出力には、インデックスの作成の確認とドキュメントのアップロードの成功が含まれます。

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

2 番目のプロジェクトの出力には、有効になっている各クエリ メソッドの検索結果が表示されます。 次の例は、単一ベクトルの検索結果を示しています。

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

コードを理解する

このセクションのコード スニペットは、読みやすくするために変更されている可能性があります。 完全な作業例については、ソース コードを参照してください。

コードを実行したので、主な手順を分解しましょう。

  1. ベクトル インデックスを作成する
  2. ドキュメントをインデックスにアップロードする
  3. インデックスのクエリを実行する

ベクトル インデックスを作成する

コンテンツをAzure AI 検索に追加する前に、コンテンツの格納方法と構造化方法を定義するインデックスを作成する必要があります。

インデックス スキーマは、ホテルのコンテンツを中心に編成されています。 サンプル データは、架空のホテルのベクトルと非ベクトルの説明で構成されます。 の次のコードは、ベクター フィールド を含むインデックス スキーマを作成します。

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();
}

重要なポイント:

  • インデックスを定義するには、フィールドのリストを作成します。

  • この特定のインデックスでは、複数の検索機能がサポートされています。

    • フルテキスト検索 ()

    • ベクター検索 ()

    • セマンティック ランク付け ()

    • ファセット検索 (でマークされたフィールド)

    • 地理空間検索 ( フィールドと )

    • フィルター処理 と並べ替え ( と でマークされたフィールド)

  • の 2 番目のパラメーターは、埋め込みモデルの出力サイズと一致する必要があるを指定します。 このクイック スタートでは、1,536 個のディメンションを使用して、 モデルと一致させます。

  • 構成では、近似最近隣 (ANN) アルゴリズムを定義します。 サポートされるアルゴリズムには、階層ナビゲーション可能 Small World (HNSW) と包括的な K ニアレスト ネイバー (KNN) が含まれます。 詳細については、 ベクトル検索の関連性を参照してください。

インデックスにドキュメントをアップロードする

新しく作成されたインデックスは空です。 インデックスを設定して検索できるようにするには、インデックス スキーマに準拠する JSON ドキュメントをアップロードする必要があります。

Azure AI 検索では、ドキュメントはインデックス作成の入力とクエリの出力の両方として機能します。 わかりやすくするために、このクイック スタートでは、事前計算されたベクターを含むサンプルのホテル ドキュメントを提供します。 運用環境のシナリオでは、多くの場合、コンテンツは接続されたデータ ソースからプルされ、 インデクサーを使用して JSON に変換されます。

次のコードは、 から検索サービスにドキュメントをアップロードします。

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);
    }
}

コードは、SearchClient パッケージによって提供されるメイン オブジェクトである Azure.Search.Documents を介して、Azure AI 検索 サービスでホストされている特定の検索インデックスと対話します。 は、次のようなインデックス操作へのアクセスを提供します。

  • データ インジェスト: 、 、

  • 検索操作: 、 、

インデックスのクエリを実行する

のクエリは、さまざまな検索パターンを示しています。 例のベクトル クエリは、次の 2 つの文字列に基づいています。

  • フルテキスト検索文字列:

  • ベクター クエリ文字列: (数学的表現にベクター化)

ベクター クエリ文字列は、意味的にはフルテキスト検索文字列に似ていますが、インデックスに存在しない用語が含まれています。 ベクトル クエリ文字列のキーワードのみの検索では、0 個の結果が返されます。 ただし、ベクトル検索では、正確なキーワードではなく意味に基づいて関連する一致が検索されます。

次の例は、基本的なベクター クエリから始まり、フィルター、キーワード検索、セマンティック再ランク付けを段階的に追加します。

メソッドは、ベクター クエリ文字列と密接に一致するドキュメントの説明を検索する基本的なシナリオを示しています。 はベクター検索を構成します。

  • は、ベクトルの類似性に基づいて返される結果の数を制限します。
  • は、検索対象のベクター フィールドを指定します。
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();
}

フィルターを使用した単一ベクター検索

Azure AI 検索では、filtersインデックス内の非ベクトル フィールドに適用されます。 メソッドは、 フィールドをフィルター処理して、無料の Wi-Fi を提供していないホテルを除外します。

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();
}

geo フィルターを使用した単一ベクター検索

地理空間フィルターを指定して、結果を特定の地理的領域に制限できます。 メソッドは、地理的なポイント (経度と緯度の座標を使用してワシントン D.C.) を指定し、300 キロメートル以内のホテルを返します。 既定では、フィルターはベクター検索の後に実行されます。

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();
}

ハイブリッド検索 では、フルテキスト クエリとベクター クエリが 1 つの要求に結合されます。 メソッドは両方のクエリ型を同時に実行し、逆ランク Fusion (RRF) を使用して結果を統合ランク付けにマージします。 RRF では、各結果セットの結果ランク付けの逆関数を使用して、マージされたランク付けが生成されます。 ハイブリッド検索スコアは、単一クエリ スコアよりも一様に小さいことに注意してください。

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;
}

メソッドは、言語理解に基づいて結果を再ランク付けするセマンティック ランク付けを示します。

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();
}

これらの結果を、前のクエリのハイブリッド検索結果と比較します。 セマンティックリランクを使用しない場合、逆ランク融合 (RRF) はテキストとベクタースコアを組み合わせてマージされた結果を生成するため、Sublime Palace Hotel は最初にランク付けされます。 セマンティック・リランクの後、スワール・カレント・ホテルはトップに移動します。

セマンティック ランカーは、マシン理解モデルを使用して、各結果がクエリの意図とどの程度一致するかを評価します。 スワール・カレント・ホテルの説明では、検索クエリのと密接に一致するについて説明しています。 近隣の食事やショッピング施設への適切な連携により、サブライムパレスホテルよりも優れた位置づけとなっています。サブライムパレスホテルは、施設の説明で徒歩圏内のアメニティを強調していません。

重要なポイント:

  • ハイブリッド検索では、キーワードに対するフルテキスト検索とベクトル検索を統合できます。 フィルターとセマンティック ランク付けは、ベクターではなくテキスト コンテンツにのみ適用されます。

  • 実際の結果には、セマンティック キャプションや強調表示など、より詳細な情報が含まれます。 このクイック スタートでは、読みやすくするために結果を変更します。 応答の完全な構造を取得するには、REST を使用して要求を実行します。

リソースをクリーンアップする

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースを動作させたままだと、お金がかかることがあります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

このクイック スタートでは、Java 用の Azure AI 検索 クライアント ライブラリを使用して、vector インデックスを作成、読み込み、クエリします。 Java クライアント ライブラリは、インデックス操作用の REST API に対する抽象化を提供します。

Azure AI 検索では、ベクター インデックスには、ベクター フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクター検索構成、およびクエリ時に評価されるベクター フィールド定義の設定があります。 インデックス - 作成または更新 (REST API) によってベクター インデックスが作成されます。

ヒント

  • すぐに始めたいですか? GitHubにsource コードをダウンロードします。
  • このクイック スタートでは、ベクター化の手順を省略し、インライン埋め込みを提供します。 独自のコンテンツ に対する統合ベクター化 の場合は、 データのインポート (新しい) ウィザードを試してください。

前提条件

  • アクティブなサブスクリプションを持つAzure アカウント。 無料でアカウントを作成できます。

  • Azure AI 検索 サービス。 このクイック スタートのほとんどは Free レベルを使用できますが、より大きなデータ ファイルには Basic 以上をお勧めします。

  • オプションのセマンティック ハイブリッド クエリに対して検索サービスで有効になっているセマンティック ランカー。

  • Java 21 (LTS) および Maven

  • Visual Studio Code

  • Git を使ってサンプルリポジトリを複製します。

  • Microsoft Entra IDを使用したキーレス認証のAzure CLI

アクセスを構成する

開始する前に、Azure AI 検索のコンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 このクイック スタートでは、認証にMicrosoft Entra IDを使用し、承認にはロールベースのアクセスを使用します。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールの使用が困難な場合は、代わりにキー ベースの認証を使用してください。

推奨されるロールベースのアクセスを構成するには:

  1. 検索サービスのロールベースのアクセスを有効にします。

  2. ユーザー アカウントに次のロールを割り当てます 。

    • Search Service サービス貢献者

    • 検索インデックス データ共同作成者

    • 検索インデックス データ閲覧者

エンドポイントを取得する

各Azure AI 検索 サービスには endpoint があります。これは、サービスを識別してネットワーク アクセスを提供する一意の URL です。 後のセクションでは、このエンドポイントを指定して、プログラムで検索サービスに接続します。

エンドポイントを取得するには:

  1. Azure ポータルにサインインし、検索サービスを選択します。

  2. 左側のウィンドウで、[ 概要] を選択します。

  3. のような形式のエンドポイントをメモしておいてください。

環境をセットアップする

  1. Git を使用してサンプル リポジトリを複製します。

    git clone https://github.com/Azure-Samples/azure-search-java-samples
    
  2. クイック スタート フォルダーに移動し、Visual Studio Codeで開きます。

    cd azure-search-java-samples/quickstart-vector-search
    code .
    
  3. で、のプレースホルダー値を Get エンドポイントで取得した URL に置き換えます。

  4. 依存関係をインストールします。

    mvn clean dependency:copy-dependencies
    

    ビルドが完了すると、プロジェクト ディレクトリに フォルダーが表示されます。

  5. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索 サービスを含むサブスクリプションを選択します。

    az login
    

コードの実行

  1. ベクター インデックスを作成します。

    mvn compile exec:java "-Dexec.mainClass=com.example.search.CreateIndex"
    
  2. 事前計算済み埋め込みを含むドキュメントを読み込みます。

    mvn compile exec:java "-Dexec.mainClass=com.example.search.UploadDocuments"
    
  3. ベクター検索クエリを実行します。

    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingle"
    
  4. (省略可能)追加のクエリ バリエーションを実行します。

    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"
    

アウトプット

の出力には、インデックス名と確認が表示されます。

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

の出力で、インデックス化された各ドキュメントの成功ステータスが表示されます。

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.

の出力には、類似性スコアでランク付けされたベクター検索結果が表示されます。

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

コードを理解する

このセクションのコード スニペットは、読みやすくするために変更されている可能性があります。 完全な作業例については、ソース コードを参照してください。

コードを実行したので、主な手順を分解しましょう。

  1. ベクトル インデックスを作成する
  2. ドキュメントをインデックスにアップロードする
  3. インデックスのクエリを実行する

ベクトル インデックスを作成する

コンテンツをAzure AI 検索に追加する前に、コンテンツの格納方法と構造化方法を定義するインデックスを作成する必要があります。

インデックス スキーマは、ホテルのコンテンツを中心に編成されています。 サンプル データは、架空のホテルのベクトルと非ベクトルの説明で構成されます。 の次のコードは、ベクター フィールド を含むインデックス スキーマを作成します。

// 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);

重要なポイント:

  • インデックスを定義するには、フィールドのリストを作成します。

  • この特定のインデックスでは、複数の検索機能がサポートされています。

    • フルテキスト検索 ()

    • ベクター検索 (を使用した)

    • セマンティック ランク付け ()

    • ファセット検索 (でマークされたフィールド)

    • 地理空間検索 ( フィールドと )

    • フィルター処理 と並べ替え ( と でマークされたフィールド)

  • 値は、埋め込みモデルの出力サイズと一致する必要があります。 このクイック スタートでは、1,536 個のディメンションを使用して、 モデルと一致させます。

  • 構成では、近似最近隣 (ANN) アルゴリズムを定義します。 サポートされるアルゴリズムには、階層ナビゲーション可能 Small World (HNSW) と包括的な K ニアレスト ネイバー (KNN) が含まれます。 詳細については、 ベクトル検索の関連性を参照してください。

インデックスにドキュメントをアップロードする

新しく作成されたインデックスは空です。 インデックスを設定して検索できるようにするには、インデックス スキーマに準拠する JSON ドキュメントをアップロードする必要があります。

Azure AI 検索では、ドキュメントはインデックス作成の入力とクエリの出力の両方として機能します。 わかりやすくするために、このクイック スタートでは、事前計算されたベクターを含むサンプルのホテル ドキュメントを提供します。 運用環境のシナリオでは、多くの場合、コンテンツは接続されたデータ ソースからプルされ、 インデクサーを使用して JSON に変換されます。

の次のコードは、ドキュメントを検索サービスにアップロードします。

// 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()));
}

コードは、SearchClient パッケージによって提供されるメイン オブジェクトである azure-search-documents を介して、Azure AI 検索 サービスでホストされている特定の検索インデックスと対話します。 は、次のような操作へのアクセスを提供します。

  • データ インジェスト: 、 、

  • 検索操作: 、 、

インデックスのクエリを実行する

検索ファイル内のクエリは、さまざまな検索パターンを示しています。 例のベクトル クエリは、次の 2 つの文字列に基づいています。

  • フルテキスト検索文字列:

  • ベクター クエリ文字列: (数学的表現にベクター化)

ベクター クエリ文字列は、意味的にはフルテキスト検索文字列に似ていますが、インデックスに存在しない用語が含まれています。 ベクトル クエリ文字列のキーワードのみの検索では、0 個の結果が返されます。 ただし、ベクトル検索では、正確なキーワードではなく意味に基づいて関連する一致が検索されます。

次の例は、基本的なベクター クエリから始まり、フィルター、キーワード検索、セマンティック再ランク付けを段階的に追加します。

は、ベクター クエリ文字列と密接に一致するドキュメントの説明を検索する基本的なシナリオを示しています。 はベクター検索を構成します。

  • は、ベクトルの類似性に基づいて返される結果の数を制限します。
  • は、検索対象のベクター フィールドを指定します。
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()));
}

フィルターを使用した単一ベクター検索

Azure AI 検索では、filtersインデックス内の非ベクトル フィールドに適用されます。 は、 フィールドにフィルターを適用して、無料の Wi-Fi を提供していないホテルを除外します。

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);

geo フィルターを使用した単一ベクター検索

地理空間フィルターを指定して、結果を特定の地理的領域に制限できます。 は地理的なポイント (経度と緯度の座標を使用してワシントン D.C.) を指定し、300 キロメートル以内のホテルを返します。 で呼び出される メソッドによって、フィルターが実行されるタイミングが決まります。 この場合、 はベクター検索の後にフィルターを実行します。

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);

ハイブリッド検索 では、フルテキスト クエリとベクター クエリが 1 つの要求に結合されます。 は両方のクエリの種類を同時に実行し、逆ランク Fusion (RRF) を使用して結果を統合ランク付けにマージします。 RRF では、各結果セットの結果ランク付けの逆関数を使用して、マージされたランク付けが生成されます。 ハイブリッド検索スコアは、単一クエリ スコアよりも一様に小さいことに注意してください。

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);

は、言語理解に基づいて結果を再ランク付けする セマンティック ランク付けを示しています。

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);

これらの結果を、前のクエリのハイブリッド検索結果と比較します。 セマンティックリランクを使用しない場合、逆ランク融合 (RRF) はテキストとベクタースコアを組み合わせてマージされた結果を生成するため、Sublime Palace Hotel は最初にランク付けされます。 セマンティック・リランクの後、スワール・カレント・ホテルはトップに移動します。

セマンティック ランカーは、マシン理解モデルを使用して、各結果がクエリの意図とどの程度一致するかを評価します。 スワール・カレント・ホテルの説明では、検索クエリのと密接に一致するについて説明しています。 近隣の食事やショッピング施設への適切な連携により、サブライムパレスホテルよりも優れた位置づけとなっています。サブライムパレスホテルは、施設の説明で徒歩圏内のアメニティを強調していません。

重要なポイント:

  • ハイブリッド検索では、キーワードに対するフルテキスト検索とベクトル検索を統合できます。 フィルターとセマンティック ランク付けは、ベクターではなくテキスト コンテンツにのみ適用されます。

  • 実際の結果には、セマンティック キャプションや強調表示など、より詳細な情報が含まれます。 このクイック スタートでは、読みやすくするために結果を変更します。 応答の完全な構造を取得するには、REST を使用して要求を実行します。

リソースをクリーンアップする

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースを動作させたままだと、お金がかかることがあります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

それ以外の場合は、次のコマンドを実行して、このクイック スタートで作成したインデックスを削除します。

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

このクイックスタートでは、JavaScript 用の Azure AI 検索 クライアント ライブラリを使用して、vector インデックスを作成、読み込み、クエリします。 JavaScript クライアント ライブラリは、インデックス操作用の REST API に対する抽象化を提供します。

Azure AI 検索では、ベクター インデックスには、ベクター フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクター検索構成、およびクエリ時に評価されるベクター フィールド定義の設定があります。 インデックス - 作成または更新 (REST API) によってベクター インデックスが作成されます。

ヒント

  • すぐに始めたいですか? GitHubにsource コードをダウンロードします。
  • このクイック スタートでは、ベクター化の手順を省略し、インライン埋め込みを提供します。 独自のコンテンツ に対する統合ベクター化 の場合は、 データのインポート (新しい) ウィザードを試してください。

前提条件

  • アクティブなサブスクリプションを持つAzure アカウント。 無料でアカウントを作成できます。

  • Azure AI 検索 サービス。 このクイック スタートのほとんどは Free レベルを使用できますが、より大きなデータ ファイルには Basic 以上をお勧めします。

  • オプションのセマンティック ハイブリッド クエリに対して検索サービスで有効になっているセマンティック ランカー。

  • Node.js 20 LTS 以降。

  • Visual Studio Code

  • Git を使ってサンプルリポジトリを複製します。

  • Microsoft Entra IDを使用したキーレス認証のAzure CLI

アクセスを構成する

開始する前に、Azure AI 検索のコンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 このクイック スタートでは、認証にMicrosoft Entra IDを使用し、承認にはロールベースのアクセスを使用します。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールの使用が困難な場合は、代わりにキー ベースの認証を使用してください。

推奨されるロールベースのアクセスを構成するには:

  1. 検索サービスのロールベースのアクセスを有効にします。

  2. ユーザー アカウントに次のロールを割り当てます 。

    • Search Service サービス貢献者

    • 検索インデックス データ共同作成者

    • 検索インデックス データ閲覧者

エンドポイントを取得する

各Azure AI 検索 サービスには endpoint があります。これは、サービスを識別してネットワーク アクセスを提供する一意の URL です。 後のセクションでは、このエンドポイントを指定して、プログラムで検索サービスに接続します。

エンドポイントを取得するには:

  1. Azure ポータルにサインインし、検索サービスを選択します。

  2. 左側のウィンドウで、[ 概要] を選択します。

  3. のような形式のエンドポイントをメモしておいてください。

環境をセットアップする

  1. Git を使用してサンプル リポジトリを複製します。

    git clone https://github.com/Azure-Samples/azure-search-javascript-samples
    
  2. クイック スタート フォルダーに移動し、Visual Studio Codeで開きます。

    cd azure-search-javascript-samples/quickstart-vector-js
    code .
    
  3. で、のプレースホルダー値を Get エンドポイントで取得した URL に置き換えます。

  4. の名前を に変更します。

    mv sample.env .env
    
  5. 依存関係をインストールします。

    npm install
    

    インストールが完了すると、プロジェクト ディレクトリに フォルダーが表示されます。

  6. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索 サービスを含むサブスクリプションを選択します。

    az login
    

コードの実行

  1. ベクター インデックスを作成します。

    node -r dotenv/config src/createIndex.js
    
  2. 事前計算済み埋め込みを含むドキュメントを読み込みます。

    node -r dotenv/config src/uploadDocuments.js
    
  3. ベクター検索クエリを実行します。

    node -r dotenv/config src/searchSingle.js
    
  4. (省略可能)追加のクエリ バリエーションを実行します。

    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
    

アウトプット

の出力には、インデックス名と確認が表示されます。

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

の出力で、インデックス化された各ドキュメントの成功ステータスが表示されます。

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.

の出力には、類似性スコアでランク付けされたベクター検索結果が表示されます。

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

コードを理解する

このセクションのコード スニペットは、読みやすくするために変更されている可能性があります。 完全な作業例については、ソース コードを参照してください。

コードを実行したので、主な手順を分解しましょう。

  1. ベクトル インデックスを作成する
  2. ドキュメントをインデックスにアップロードする
  3. インデックスのクエリを実行する

ベクトル インデックスを作成する

コンテンツをAzure AI 検索に追加する前に、コンテンツの格納方法と構造化方法を定義するインデックスを作成する必要があります。

インデックス スキーマは、ホテルのコンテンツを中心に編成されています。 サンプル データは、架空のホテルのベクトルと非ベクトルの説明で構成されます。 の次のコードは、ベクター フィールド を含むインデックス スキーマを作成します。

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);

重要なポイント:

  • インデックスを定義するには、フィールドのリストを作成します。

  • この特定のインデックスでは、複数の検索機能がサポートされています。

    • フルテキスト検索 ()

    • ベクター検索 (を使用した)

    • セマンティック ランク付け ()

    • ファセット検索 (でマークされたフィールド)

    • 地理空間検索 ( フィールドと )

    • フィルター処理 と並べ替え ( と でマークされたフィールド)

  • プロパティは、埋め込みモデルの出力サイズと一致する必要があります。 このクイック スタートでは、1,536 個のディメンションを使用して、 モデルと一致させます。

  • 構成では、近似最近隣 (ANN) アルゴリズムを定義します。 サポートされるアルゴリズムには、階層ナビゲーション可能 Small World (HNSW) と包括的な K ニアレスト ネイバー (KNN) が含まれます。 詳細については、 ベクトル検索の関連性を参照してください。

インデックスにドキュメントをアップロードする

新しく作成されたインデックスは空です。 インデックスを設定して検索できるようにするには、インデックス スキーマに準拠する JSON ドキュメントをアップロードする必要があります。

Azure AI 検索では、ドキュメントはインデックス作成の入力とクエリの出力の両方として機能します。 わかりやすくするために、このクイック スタートでは、事前計算されたベクターを含むサンプルのホテル ドキュメントを提供します。 運用環境のシナリオでは、多くの場合、コンテンツは接続されたデータ ソースからプルされ、 インデクサーを使用して JSON に変換されます。

の次のコードは、ドキュメントを検索サービスにアップロードします。

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}`);
}

コードは、SearchClient パッケージによって提供されるメイン オブジェクトである @azure/search-documents を介して、Azure AI 検索 サービスでホストされている特定の検索インデックスと対話します。 は、次のようなインデックス操作へのアクセスを提供します。

  • データ インジェスト: 、 、

  • 検索操作: 、 、

インデックスのクエリを実行する

検索ファイル内のクエリは、さまざまな検索パターンを示しています。 例のベクトル クエリは、次の 2 つの文字列に基づいています。

  • フルテキスト検索文字列:

  • ベクター クエリ文字列: (数学的表現にベクター化)

ベクター クエリ文字列は、意味的にはフルテキスト検索文字列に似ていますが、インデックスに存在しない用語が含まれています。 ベクトル クエリ文字列のキーワードのみの検索では、0 個の結果が返されます。 ただし、ベクトル検索では、正確なキーワードではなく意味に基づいて関連する一致が検索されます。

次の例は、基本的なベクター クエリから始まり、フィルター、キーワード検索、セマンティック再ランク付けを段階的に追加します。

は、ベクター クエリ文字列と密接に一致するドキュメントの説明を検索する基本的なシナリオを示しています。 オブジェクトは、ベクトル検索を構成します。

  • は、ベクトルの類似性に基づいて返される結果の数を制限します。
  • は、検索対象のベクター フィールドを指定します。
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}`);
}

フィルターを使用した単一ベクター検索

Azure AI 検索では、filtersインデックス内の非ベクトル フィールドに適用されます。 は、 フィールドにフィルターを適用して、無料の Wi-Fi を提供していないホテルを除外します。

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);

geo フィルターを使用した単一ベクター検索

地理空間フィルターを指定して、結果を特定の地理的領域に制限できます。 は地理的なポイント (経度と緯度の座標を使用してワシントン D.C.) を指定し、300 キロメートル以内のホテルを返します。 プロパティは、フィルターを実行するタイミングを決定します。 この場合、 はベクター検索の後にフィルターを実行します。

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"
    }
};

ハイブリッド検索 では、フルテキスト クエリとベクター クエリが 1 つの要求に結合されます。 は両方のクエリの種類を同時に実行し、逆ランク Fusion (RRF) を使用して結果を統合ランク付けにマージします。 RRF では、各結果セットの結果ランク付けの逆関数を使用して、マージされたランク付けが生成されます。 ハイブリッド検索スコアは、単一クエリ スコアよりも一様に小さいことに注意してください。

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);

は、言語理解に基づいて結果を再ランク付けする セマンティック ランク付けを示しています。

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}`);
}

これらの結果を、前のクエリのハイブリッド検索結果と比較します。 セマンティックリランクを使用しない場合、逆ランク融合 (RRF) はテキストとベクタースコアを組み合わせてマージされた結果を生成するため、Sublime Palace Hotel は最初にランク付けされます。 セマンティック・リランクの後、スワール・カレント・ホテルはトップに移動します。

セマンティック ランカーは、マシン理解モデルを使用して、各結果がクエリの意図とどの程度一致するかを評価します。 スワール・カレント・ホテルの説明では、検索クエリのと密接に一致するについて説明しています。 近隣の食事やショッピング施設への適切な連携により、サブライムパレスホテルよりも優れた位置づけとなっています。サブライムパレスホテルは、施設の説明で徒歩圏内のアメニティを強調していません。

重要なポイント:

  • ハイブリッド検索では、キーワードに対するフルテキスト検索とベクトル検索を統合できます。 フィルターとセマンティック ランク付けは、ベクターではなくテキスト コンテンツにのみ適用されます。

  • 実際の結果には、セマンティック キャプションや強調表示など、より詳細な情報が含まれます。 このクイック スタートでは、読みやすくするために結果を変更します。 応答の完全な構造を取得するには、REST を使用して要求を実行します。

リソースをクリーンアップする

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースを動作させたままだと、お金がかかることがあります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

それ以外の場合は、次のコマンドを実行して、このクイック スタートで作成したインデックスを削除します。

node -r dotenv/config src/deleteIndex.js

このクイック スタートでは、Azure AI 検索 Python vector インデックスを作成、読み込み、クエリを実行します。 Python クライアント ライブラリは、インデックス操作用の REST API に対する抽象化を提供します。

Azure AI 検索では、ベクター インデックスには、ベクター フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクター検索構成、およびクエリ時に評価されるベクター フィールド定義の設定があります。 インデックス - 作成または更新 (REST API) によってベクター インデックスが作成されます。

ヒント

  • すぐに始めたいですか? GitHubにsource コードをダウンロードします。
  • このクイック スタートでは、ベクター化の手順を省略し、インライン埋め込みを提供します。 独自のコンテンツ に対する統合ベクター化 の場合は、 データのインポート (新しい) ウィザードを試してください。

前提条件

  • アクティブなサブスクリプションを持つAzure アカウント。 無料でアカウントを作成できます。

  • Azure AI 検索 サービス。 このクイック スタートのほとんどは Free レベルを使用できますが、より大きなデータ ファイルには Basic 以上をお勧めします。

  • オプションのセマンティック ハイブリッド クエリに対して検索サービスで有効になっているセマンティック ランカー。

  • Python 3.8以降

  • Visual Studio CodePython および Jupyter 拡張子を使用します。

  • Git を使ってサンプルリポジトリを複製します。

  • Microsoft Entra IDを使用したキーレス認証のAzure CLI

アクセスを構成する

開始する前に、Azure AI 検索のコンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 このクイック スタートでは、認証にMicrosoft Entra IDを使用し、承認にはロールベースのアクセスを使用します。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールの使用が困難な場合は、代わりにキー ベースの認証を使用してください。

推奨されるロールベースのアクセスを構成するには:

  1. 検索サービスのロールベースのアクセスを有効にします。

  2. ユーザー アカウントに次のロールを割り当てます 。

    • Search Service サービス貢献者

    • 検索インデックス データ共同作成者

    • 検索インデックス データ閲覧者

エンドポイントを取得する

各Azure AI 検索 サービスには endpoint があります。これは、サービスを識別してネットワーク アクセスを提供する一意の URL です。 後のセクションでは、このエンドポイントを指定して、プログラムで検索サービスに接続します。

エンドポイントを取得するには:

  1. Azure ポータルにサインインし、検索サービスを選択します。

  2. 左側のウィンドウで、[ 概要] を選択します。

  3. のような形式のエンドポイントをメモしておいてください。

環境をセットアップする

  1. Git を使用してサンプル リポジトリを複製します。

    git clone https://github.com/Azure-Samples/azure-search-python-samples
    
  2. クイック スタート フォルダーに移動し、Visual Studio Codeで開きます。

    cd azure-search-python-samples/Quickstart-Vector-Search
    code .
    
  3. で、のプレースホルダー値を Get エンドポイントで取得した URL に置き換えます。

  4. の名前を に変更します。

    mv sample.env .env
    
  5. を開きます。

  6. Ctrl + Shift + P キーを押し、[Notebook: Select Notebook Kernel]\(ノートブック カーネルの選択\) を選択し、画面の指示に従って仮想環境を作成します。 依存関係用にrequirements.txtを選択します。

    完了すると、プロジェクト ディレクトリに フォルダーが表示されます。

  7. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索 サービスを含むサブスクリプションを選択します。

    az login
    

コードの実行

  1. [ ] セルを実行して、必要なパッケージをインストールし、環境変数を読み込みます。

  2. 残りのセルを順番に実行してベクター インデックスを作成し、ドキュメントをアップロードし、さまざまな種類のベクター クエリを実行します。

アウトプット

各コード セルは、その出力をノートブックに出力します。 次の例は、 の出力です。これは、類似性スコアでランク付けされたベクター検索結果を示しています。

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

コードを理解する

このセクションのコード スニペットは、読みやすくするために変更されている可能性があります。 完全な作業例については、ソース コードを参照してください。

コードを実行したので、主な手順を分解しましょう。

  1. ベクトル インデックスを作成する
  2. ドキュメントをインデックスにアップロードする
  3. インデックスのクエリを実行する

ベクトル インデックスを作成する

コンテンツをAzure AI 検索に追加する前に、コンテンツの格納方法と構造化方法を定義するインデックスを作成する必要があります。

インデックス スキーマは、ホテルのコンテンツを中心に編成されています。 サンプル データは、架空のホテルのベクトルと非ベクトルの説明で構成されます。 ノートブックの [ ] セルは、ベクター フィールド を含むインデックス スキーマを作成します。

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
]

重要なポイント:

  • インデックスを定義するには、フィールドのリストを作成します。 各フィールドは、フィールドの種類とその設定を定義するヘルパー メソッドを使用して作成されます。

  • この特定のインデックスでは、複数の検索機能がサポートされています。

    • フルテキスト検索 ()

    • ベクター検索 (を使用した)

    • セマンティック ランク付け ()

    • ファセット検索 (でマークされたフィールド)

    • 地理空間検索 ( フィールドと )

    • フィルター処理 と並べ替え ( と でマークされたフィールド)

  • プロパティは、埋め込みモデルの出力サイズと一致する必要があります。 このクイック スタートでは、1,536 個のディメンションを使用して、 モデルと一致させます。

  • 構成では、近似最近隣 (ANN) アルゴリズムを定義します。 サポートされるアルゴリズムには、階層ナビゲーション可能 Small World (HNSW) と包括的な K ニアレスト ネイバー (KNN) が含まれます。 詳細については、 ベクトル検索の関連性を参照してください。

インデックスにドキュメントをアップロードする

新しく作成されたインデックスは空です。 インデックスを設定して検索できるようにするには、インデックス スキーマに準拠する JSON ドキュメントをアップロードする必要があります。

Azure AI 検索では、ドキュメントはインデックス作成の入力とクエリの出力の両方として機能します。 わかりやすくするために、このクイック スタートでは、事前計算されたベクターを含むサンプルのホテル ドキュメントを提供します。 運用環境のシナリオでは、多くの場合、コンテンツは接続されたデータ ソースからプルされ、 インデクサーを使用して JSON に変換されます。

セルと セルは、ドキュメントをインデックスに読み込みます。

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}")

コードは、SearchClient パッケージによって提供されるメイン オブジェクトである azure-search-documents を介して、Azure AI 検索 サービスでホストされている特定の検索インデックスと対話します。 は、次のようなインデックス操作へのアクセスを提供します。

  • データ インジェスト: 、 、

  • 検索操作: 、 、

インデックスのクエリを実行する

ノートブック内のクエリは、さまざまな検索パターンを示しています。 例のベクトル クエリは、次の 2 つの文字列に基づいています。

  • フルテキスト検索文字列:

  • ベクター クエリ文字列: (数学的表現にベクター化)

ベクター クエリ文字列は、意味的にはフルテキスト検索文字列に似ていますが、インデックスに存在しない用語が含まれています。 ベクトル クエリ文字列のキーワードのみの検索では、0 個の結果が返されます。 ただし、ベクトル検索では、正確なキーワードではなく意味に基づいて関連する一致が検索されます。

次の例は、基本的なベクター クエリから始まり、フィルター、キーワード検索、セマンティック再ランク付けを段階的に追加します。

セルは、ベクター クエリ文字列と密接に一致するドキュメントの説明を検索する基本的なシナリオを示しています。 はベクター検索を構成します。

  • は、ベクトルの類似性に基づいて返される結果の数を制限します。
  • は、検索対象のベクター フィールドを指定します。
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
)

フィルターを使用した単一ベクター検索

Azure AI 検索では、filtersインデックス内の非ベクトル フィールドに適用されます。 [ ] セルは、 フィールドをフィルター処理して、無料の Wi-Fi を提供していないホテルを除外します。

# 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
)

geo フィルターを使用した単一ベクター検索

地理空間フィルターを指定して、結果を特定の地理的領域に制限できます。 [ ] セルは、地理的なポイント (経度と緯度の座標を使用してワシントン D.C.) を指定し、300 キロメートル以内のホテルを返します。 パラメーターは、フィルターを実行するタイミングを決定します。 この場合、 はベクター検索の後にフィルターを実行します。

# 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]
)

ハイブリッド検索 では、フルテキスト クエリとベクター クエリが 1 つの要求に結合されます。 セルは両方のクエリの種類を同時に実行し、逆ランク Fusion (RRF) を使用して結果を統合ランク付けにマージします。 RRF では、各結果セットの結果ランク付けの逆関数を使用して、マージされたランク付けが生成されます。 ハイブリッド検索スコアは、単一クエリ スコアよりも一様に小さいことに注意してください。

# 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
)

セルは、言語理解に基づいて結果を再ランク付けするセマンティック ランク付けを示しています。

# 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
)

これらの結果を、前のクエリのハイブリッド検索結果と比較します。 セマンティックリランクを使用しない場合、逆ランク融合 (RRF) はテキストとベクタースコアを組み合わせてマージされた結果を生成するため、Sublime Palace Hotel は最初にランク付けされます。 セマンティック・リランクの後、スワール・カレント・ホテルはトップに移動します。

セマンティック ランカーは、マシン理解モデルを使用して、各結果がクエリの意図とどの程度一致するかを評価します。 スワール・カレント・ホテルの説明では、検索クエリのと密接に一致するについて説明しています。 近隣の食事やショッピング施設への適切な連携により、サブライムパレスホテルよりも優れた位置づけとなっています。サブライムパレスホテルは、施設の説明で徒歩圏内のアメニティを強調していません。

重要なポイント:

  • ハイブリッド検索では、キーワードに対するフルテキスト検索とベクトル検索を統合できます。 フィルターとセマンティック ランク付けは、ベクターではなくテキスト コンテンツにのみ適用されます。

  • 実際の結果には、セマンティック キャプションや強調表示など、より詳細な情報が含まれます。 このクイック スタートでは、読みやすくするために結果を変更します。 応答の完全な構造を取得するには、REST を使用して要求を実行します。

リソースをクリーンアップする

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースを動作させたままだと、お金がかかることがあります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

それ以外の場合は、 コード セルを実行して、このクイック スタートで作成したインデックスを削除できます。

このクイック スタートでは、JavaScript 用の Azure AI 検索 クライアント ライブラリ (TypeScript と互換性があります) を使用して、vector インデックスを作成、読み込み、クエリします。 JavaScript クライアント ライブラリは、インデックス操作用の REST API に対する抽象化を提供します。

Azure AI 検索では、ベクター インデックスには、ベクター フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクター検索構成、およびクエリ時に評価されるベクター フィールド定義の設定があります。 インデックス - 作成または更新 (REST API) によってベクター インデックスが作成されます。

ヒント

  • すぐに始めたいですか? GitHubにsource コードをダウンロードします。
  • このクイック スタートでは、ベクター化の手順を省略し、インライン埋め込みを提供します。 独自のコンテンツ に対する統合ベクター化 の場合は、 データのインポート (新しい) ウィザードを試してください。

前提条件

  • アクティブなサブスクリプションを持つAzure アカウント。 無料でアカウントを作成できます。

  • Azure AI 検索 サービス。 このクイック スタートのほとんどは Free レベルを使用できますが、より大きなデータ ファイルには Basic 以上をお勧めします。

  • オプションのセマンティック ハイブリッド クエリに対して検索サービスで有効になっているセマンティック ランカー。

  • コンパイル済みコードを実行するには、20 LTS 以降をNode.js します。

  • TypeScript で TypeScript を JavaScript にコンパイルします。

  • Visual Studio Code

  • Git を使ってサンプルリポジトリを複製します。

  • Microsoft Entra IDを使用したキーレス認証のAzure CLI

アクセスを構成する

開始する前に、Azure AI 検索のコンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 このクイック スタートでは、認証にMicrosoft Entra IDを使用し、承認にはロールベースのアクセスを使用します。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールの使用が困難な場合は、代わりにキー ベースの認証を使用してください。

推奨されるロールベースのアクセスを構成するには:

  1. 検索サービスのロールベースのアクセスを有効にします。

  2. ユーザー アカウントに次のロールを割り当てます 。

    • Search Service サービス貢献者

    • 検索インデックス データ共同作成者

    • 検索インデックス データ閲覧者

エンドポイントを取得する

各Azure AI 検索 サービスには endpoint があります。これは、サービスを識別してネットワーク アクセスを提供する一意の URL です。 後のセクションでは、このエンドポイントを指定して、プログラムで検索サービスに接続します。

エンドポイントを取得するには:

  1. Azure ポータルにサインインし、検索サービスを選択します。

  2. 左側のウィンドウで、[ 概要] を選択します。

  3. のような形式のエンドポイントをメモしておいてください。

環境をセットアップする

  1. Git を使用してサンプル リポジトリを複製します。

    git clone https://github.com/Azure-Samples/azure-search-javascript-samples
    
  2. クイック スタート フォルダーに移動し、Visual Studio Codeで開きます。

    cd azure-search-javascript-samples/quickstart-vector-ts
    code .
    
  3. で、のプレースホルダー値を Get エンドポイントで取得した URL に置き換えます。

  4. の名前を に変更します。

    mv sample.env .env
    
  5. 依存関係をインストールします。

    npm install
    

    インストールが完了すると、プロジェクト ディレクトリに フォルダーが表示されます。

  6. TypeScript ファイルをビルドします。

    npm run build
    
  7. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索 サービスを含むサブスクリプションを選択します。

    az login
    

コードの実行

  1. ベクター インデックスを作成します。

    node -r dotenv/config dist/createIndex.js
    
  2. 事前計算済み埋め込みを含むドキュメントを読み込みます。

    node -r dotenv/config dist/uploadDocuments.js
    
  3. ベクター検索クエリを実行します。

    node -r dotenv/config dist/searchSingle.js
    
  4. (省略可能)追加のクエリ バリエーションを実行します。

    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
    

    これらのコマンドは、以前に TypeScript から JavaScript にトランスパイルした際に使用したため、フォルダー内のファイルを実行します。

アウトプット

の出力には、インデックス名と確認が表示されます。

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

の出力で、インデックス化された各ドキュメントの成功ステータスが表示されます。

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.

の出力には、類似性スコアでランク付けされたベクター検索結果が表示されます。

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

コードを理解する

このセクションのコード スニペットは、読みやすくするために変更されている可能性があります。 完全な作業例については、ソース コードを参照してください。

コードを実行したので、主な手順を分解しましょう。

  1. ベクトル インデックスを作成する
  2. ドキュメントをインデックスにアップロードする
  3. インデックスのクエリを実行する

ベクトル インデックスを作成する

コンテンツをAzure AI 検索に追加する前に、コンテンツの格納方法と構造化方法を定義するインデックスを作成する必要があります。

インデックス スキーマは、ホテルのコンテンツを中心に編成されています。 サンプル データは、架空のホテルのベクトルと非ベクトルの説明で構成されます。 の次のコードは、ベクター フィールド を含むインデックス スキーマを作成します。

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);

重要なポイント:

  • インデックスを定義するには、フィールドのリストを作成します。

  • この特定のインデックスでは、複数の検索機能がサポートされています。

    • フルテキスト検索 ()

    • ベクター検索 (を使用した)

    • セマンティック ランク付け ()

    • ファセット検索 (でマークされたフィールド)

    • 地理空間検索 ( フィールドと )

    • フィルター処理 と並べ替え ( と でマークされたフィールド)

  • プロパティは、埋め込みモデルの出力サイズと一致する必要があります。 このクイック スタートでは、1,536 個のディメンションを使用して、 モデルと一致させます。

  • 構成では、近似最近隣 (ANN) アルゴリズムを定義します。 サポートされるアルゴリズムには、階層ナビゲーション可能 Small World (HNSW) と包括的な K ニアレスト ネイバー (KNN) が含まれます。 詳細については、 ベクトル検索の関連性を参照してください。

インデックスにドキュメントをアップロードする

新しく作成されたインデックスは空です。 インデックスを設定して検索できるようにするには、インデックス スキーマに準拠する JSON ドキュメントをアップロードする必要があります。

Azure AI 検索では、ドキュメントはインデックス作成の入力とクエリの出力の両方として機能します。 わかりやすくするために、このクイック スタートでは、事前計算されたベクターを含むサンプルのホテル ドキュメントを提供します。 運用環境のシナリオでは、多くの場合、コンテンツは接続されたデータ ソースからプルされ、 インデクサーを使用して JSON に変換されます。

の次のコードは、ドキュメントを検索サービスにアップロードします。

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}`);
}

コードは、SearchClient パッケージによって提供されるメイン オブジェクトである @azure/search-documents を介して、Azure AI 検索 サービスでホストされている特定の検索インデックスと対話します。 は、次のようなインデックス操作へのアクセスを提供します。

  • データ インジェスト: 、 、

  • 検索操作: 、 、

インデックスのクエリを実行する

検索ファイル内のクエリは、さまざまな検索パターンを示しています。 例のベクトル クエリは、次の 2 つの文字列に基づいています。

  • フルテキスト検索文字列:

  • ベクター クエリ文字列: (数学的表現にベクター化)

ベクター クエリ文字列は、意味的にはフルテキスト検索文字列に似ていますが、インデックスに存在しない用語が含まれています。 ベクトル クエリ文字列のキーワードのみの検索では、0 個の結果が返されます。 ただし、ベクトル検索では、正確なキーワードではなく意味に基づいて関連する一致が検索されます。

次の例は、基本的なベクター クエリから始まり、フィルター、キーワード検索、セマンティック再ランク付けを段階的に追加します。

は、ベクター クエリ文字列と密接に一致するドキュメントの説明を検索する基本的なシナリオを示しています。 オブジェクトは、ベクトル検索を構成します。

  • は、ベクトルの類似性に基づいて返される結果の数を制限します。
  • は、検索対象のベクター フィールドを指定します。
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}`);
}

フィルターを使用した単一ベクター検索

Azure AI 検索では、filtersインデックス内の非ベクトル フィールドに適用されます。 は、 フィールドにフィルターを適用して、無料の Wi-Fi を提供していないホテルを除外します。

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);

geo フィルターを使用した単一ベクター検索

地理空間フィルターを指定して、結果を特定の地理的領域に制限できます。 は地理的なポイント (経度と緯度の座標を使用してワシントン D.C.) を指定し、300 キロメートル以内のホテルを返します。 プロパティは、フィルターを実行するタイミングを決定します。 この場合、 はベクター検索の後にフィルターを実行します。

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"
    }
};

ハイブリッド検索 では、フルテキスト クエリとベクター クエリが 1 つの要求に結合されます。 は両方のクエリの種類を同時に実行し、逆ランク Fusion (RRF) を使用して結果を統合ランク付けにマージします。 RRF では、各結果セットの結果ランク付けの逆関数を使用して、マージされたランク付けが生成されます。 ハイブリッド検索スコアは、単一クエリ スコアよりも一様に小さいことに注意してください。

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);

は、言語理解に基づいて結果を再ランク付けする セマンティック ランク付けを示しています。

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}`);
}

これらの結果を、前のクエリのハイブリッド検索結果と比較します。 セマンティックリランクを使用しない場合、逆ランク融合 (RRF) はテキストとベクタースコアを組み合わせてマージされた結果を生成するため、Sublime Palace Hotel は最初にランク付けされます。 セマンティック・リランクの後、スワール・カレント・ホテルはトップに移動します。

セマンティック ランカーは、マシン理解モデルを使用して、各結果がクエリの意図とどの程度一致するかを評価します。 スワール・カレント・ホテルの説明では、検索クエリのと密接に一致するについて説明しています。 近隣の食事やショッピング施設への適切な連携により、サブライムパレスホテルよりも優れた位置づけとなっています。サブライムパレスホテルは、施設の説明で徒歩圏内のアメニティを強調していません。

重要なポイント:

  • ハイブリッド検索では、キーワードに対するフルテキスト検索とベクトル検索を統合できます。 フィルターとセマンティック ランク付けは、ベクターではなくテキスト コンテンツにのみ適用されます。

  • 実際の結果には、セマンティック キャプションや強調表示など、より詳細な情報が含まれます。 このクイック スタートでは、読みやすくするために結果を変更します。 応答の完全な構造を取得するには、REST を使用して要求を実行します。

リソースをクリーンアップする

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースを動作させたままだと、お金がかかることがあります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

それ以外の場合は、次のコマンドを実行して、このクイック スタートで作成したインデックスを削除します。

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

このクイック スタートでは、Azure AI 検索 REST API を使用して、vector インデックスを作成、読み込み、クエリします。

Azure AI 検索では、ベクター インデックスには、ベクター フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクター検索構成、およびクエリ時に評価されるベクター フィールド定義の設定があります。 インデックス - 作成または更新 (REST API) によってベクター インデックスが作成されます。

ヒント

  • すぐに始めたいですか? GitHubにsource コードをダウンロードします。
  • このクイック スタートでは、ベクター化の手順を省略し、インライン埋め込みを提供します。 独自のコンテンツ に対する統合ベクター化 の場合は、 データのインポート (新しい) ウィザードを試してください。

前提条件

  • アクティブなサブスクリプションを持つAzure アカウント。 無料でアカウントを作成できます。

  • Azure AI 検索 サービス。 このクイック スタートのほとんどは Free レベルを使用できますが、より大きなデータ ファイルには Basic 以上をお勧めします。

  • オプションのセマンティック ハイブリッド クエリに対して検索サービスで有効になっているセマンティック ランカー。

  • Visual Studio CodeREST クライアント拡張機能

  • Git を使ってサンプルリポジトリを複製します。

  • Microsoft Entra IDを使用したキーレス認証のAzure CLI

アクセスを構成する

開始する前に、Azure AI 検索のコンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 このクイック スタートでは、認証にMicrosoft Entra IDを使用し、承認にはロールベースのアクセスを使用します。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールの使用が困難な場合は、代わりにキー ベースの認証を使用してください。

推奨されるロールベースのアクセスを構成するには:

  1. 検索サービスのロールベースのアクセスを有効にします。

  2. ユーザー アカウントに次のロールを割り当てます 。

    • Search Service サービス貢献者

    • 検索インデックス データ共同作成者

    • 検索インデックス データ閲覧者

エンドポイントを取得する

各Azure AI 検索 サービスには endpoint があります。これは、サービスを識別してネットワーク アクセスを提供する一意の URL です。 後のセクションでは、このエンドポイントを指定して、プログラムで検索サービスに接続します。

エンドポイントを取得するには:

  1. Azure ポータルにサインインし、検索サービスを選択します。

  2. 左側のウィンドウで、[ 概要] を選択します。

  3. のような形式のエンドポイントをメモしておいてください。

環境をセットアップする

  1. Git を使用してサンプル リポジトリを複製します。

    git clone https://github.com/Azure-Samples/azure-search-rest-samples
    
  2. クイック スタート フォルダーに移動し、Visual Studio Codeで開きます。

    cd azure-search-rest-samples/Quickstart-vectors
    code .
    
  3. で、のプレースホルダー値を Get エンドポイントで取得した URL に置き換えます。

  4. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索 サービスを含むサブスクリプションを選択します。

    az login
    
  5. Microsoft Entra IDを使用したキーレス認証の場合は、アクセス トークンを生成します。

    az account get-access-token --scope https://search.azure.com/.default --query accessToken -o tsv
    
  6. 前のステップから取得したトークンでプレースホルダーの値を置き換えます。

コードの実行

  1. [ で、[要求の 送信 ] を選択して接続を確認します。

    隣接するウィンドウに応答が表示されます。 既存のインデックスがある場合は、そのインデックスが一覧表示されます。 それ以外の場合は、リストは空です。 HTTP コードが 場合は、続行する準備が整います。

  2. 残りの要求を順番に送信して、ベクター インデックスの作成、ドキュメントのアップロード、さまざまな種類のベクター クエリの実行を行います。

アウトプット

各クエリ要求は JSON 結果を返します。 次の例は、 要求の出力です。これは、類似性スコアでランク付けされたベクター検索結果を示しています。

{
  "@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"
      ]
    }
  ]
}

コードを理解する

このセクションのコード スニペットは、読みやすくするために変更されている可能性があります。 完全な作業例については、ソース コードを参照してください。

コードを実行したので、主な手順を分解しましょう。

  1. ベクトル インデックスを作成する
  2. ドキュメントをインデックスにアップロードする
  3. インデックスのクエリを実行する

ベクトル インデックスを作成する

コンテンツをAzure AI 検索に追加する前に、コンテンツの格納方法と構造化方法を定義するインデックスを作成する必要があります。 このクイック スタートでは 、Indexes - Create (REST API) を呼び出して、 という名前のベクター インデックスとその物理データ構造を検索サービスに構築します。

インデックス スキーマは、ホテルのコンテンツを中心に編成されています。 サンプル データは、架空のホテルのベクトルと非ベクトルの説明で構成されます。 次の抜粋は、 要求のキー構造を示しています。

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" }]
                }
            }
        ]
    }
}

重要なポイント:

  • この特定のインデックスでは、複数の検索機能がサポートされています。

    • フルテキスト検索 ( が に設定されているフィールド)

    • ベクター検索 (を使用した)

    • セマンティック ランク付け ( 構成)

    • ファセット検索 ( が に設定されているフィールド)

    • 地理空間検索 ( フィールドと )

    • フィルター処理 と並べ替え ( と が に設定されているフィールド)

  • プロパティは、埋め込みモデルの出力サイズと一致する必要があります。 このクイック スタートでは、1,536 個のディメンションを使用して、 モデルと一致させます。

  • セクションでは、近似最近傍 (ANN) アルゴリズムを定義します。 サポートされるアルゴリズムには、階層ナビゲーション可能 Small World (HNSW) と包括的な K ニアレスト ネイバー (KNN) が含まれます。 詳細については、 ベクトル検索の関連性を参照してください。

インデックスにドキュメントをアップロードする

新しく作成されたインデックスは空です。 インデックスを設定して検索できるようにするには、インデックス スキーマに準拠する JSON ドキュメントをアップロードする必要があります。

Azure AI 検索では、ドキュメントはインデックス作成の入力とクエリの出力の両方として機能します。 わかりやすくするために、このクイック スタートでは、サンプルのホテル ドキュメントをインライン JSON として提供します。 ただし、運用環境のシナリオでは、多くの場合、コンテンツは接続されたデータ ソースからプルされ、 インデクサーを使用して JSON に変換されます。

このクイック スタートでは 、Documents - Index (REST API) を呼び出して、サンプルのホテル ドキュメントをインデックスに追加します。 次の抜粋は、 要求の構造を示しています。

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
    ]
}

重要なポイント:

  • 配列内の各ドキュメントはホテルを表し、インデックス スキーマに一致するフィールドが含まれています。 パラメーターは、各ドキュメントに対して実行する操作を指定します。 このクイック スタートでは、 を使用します。ドキュメントが存在しない場合はドキュメントを追加し、存在する場合はドキュメントを更新します。

  • ペイロード内のドキュメントは、インデックス スキーマで定義されているフィールドで構成されます。

インデックスのクエリを実行する

サンプル ファイル内のクエリは、さまざまな検索パターンを示しています。 例のベクトル クエリは、次の 2 つの文字列に基づいています。

  • フルテキスト検索文字列:

  • ベクター クエリ文字列: (数学的表現にベクター化)

ベクター クエリ文字列は、意味的にはフルテキスト検索文字列に似ていますが、インデックスに存在しない用語が含まれています。 ベクトル クエリ文字列のキーワードのみの検索では、0 個の結果が返されます。 ただし、ベクトル検索では、正確なキーワードではなく意味に基づいて関連する一致が検索されます。

次の例は、基本的なベクター クエリから始まり、フィルター、キーワード検索、セマンティック再ランク付けを段階的に追加します。

要求は、ベクター クエリ文字列と密接に一致するドキュメントの説明を検索する基本的なシナリオを示しています。 配列は、ベクトル検索を構成します。

  • は、ベクトルの類似性に基づいて返される結果の数を制限します。
  • は、検索対象のベクター フィールドを指定します。
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
        }
    ]
}

フィルターを使用した単一ベクター検索

Azure AI 検索では、filtersインデックス内の非ベクトル フィールドに適用されます。 要求では、 フィールドをフィルター処理して、無料 Wi-Fi を提供していないホテルを除外します。

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
        }
    ]
}

geo フィルターを使用した単一ベクター検索

地理空間フィルターを指定して、結果を特定の地理的領域に制限できます。 要求は、地理的なポイント (経度と緯度の座標を使用してワシントン D.C.) を指定し、300 キロメートル以内のホテルを返します。 パラメーターは、フィルターを実行するタイミングを決定します。 この場合、 はベクター検索の後にフィルターを実行します。

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
        }
    ]
}

ハイブリッド検索 では、フルテキスト クエリとベクター クエリが 1 つの要求に結合されます。 リクエストは両方のクエリタイプを同時に実行し、リシプロカルランクフュージョン (RRF) を使用して結果を統合されたランキングにマージします。 RRF では、各結果セットの結果ランク付けの逆関数を使用して、マージされたランク付けが生成されます。 ハイブリッド検索スコアは、単一クエリ スコアよりも一様に小さいことに注意してください。

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
        }
    ]
}

要求は、言語理解に基づいて結果を再ランク付けするセマンティック ランク付けを示しています。

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
        }
    ]
}

これらの結果を、前のクエリのハイブリッド検索結果と比較します。 セマンティックリランクを使用しない場合、逆ランク融合 (RRF) はテキストとベクタースコアを組み合わせてマージされた結果を生成するため、Sublime Palace Hotel は最初にランク付けされます。 セマンティック・リランクの後、スワール・カレント・ホテルはトップに移動します。

セマンティック ランカーは、マシン理解モデルを使用して、各結果がクエリの意図とどの程度一致するかを評価します。 スワール・カレント・ホテルの説明では、検索クエリのと密接に一致するについて説明しています。 近隣の食事やショッピング施設への適切な連携により、サブライムパレスホテルよりも優れた位置づけとなっています。サブライムパレスホテルは、施設の説明で徒歩圏内のアメニティを強調していません。

重要なポイント:

  • ハイブリッド検索では、キーワードに対するフルテキスト検索とベクトル検索を統合できます。 フィルターとセマンティック ランク付けは、ベクターではなくテキスト コンテンツにのみ適用されます。

リソースをクリーンアップする

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースを動作させたままだと、お金がかかることがあります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

それ以外の場合は、このクイックスタートで作成したインデックスを削除する 要求を送信できます。