クライアント アプリでオートコンプリートと検索候補を追加する

入力と並行した検索は、クエリの生産性を向上させるための一般的な手法です。 Azure AI 検索では、このエクスペリエンスは、"オートコンプリート" によってサポートされます。これは部分的な入力に基づいて用語または語句を補完します ("micro" を入力すると、"microchip"、"microscope"、"microsoft"、その他の "micro" に一致するもので補完されます)。 2 つ目のユーザー エクスペリエンスは、"検索候補"、つまり、一致するドキュメントの短い一覧です (そのブックに関する詳細ページにリンクできるように、ブックのタイトルを ID とともに返します)。 オートコンプリートも検索候補も、インデックスの一致を前提としません。 このサービスでは、オートコンプリートされたクエリや結果がゼロの検索候補は提供されません。

Azure AI Search でこれらのエクスペリエンスを実装するには:

  • インデックス スキーマに suggester を追加します。
  • オートコンプリートまたは検索候補 の API を要求で呼び出すクエリを作成します。
  • クライアント アプリで入力と並行した検索操作を処理するための UI コントロールを追加します。 このために既存の JavaScript ライブラリを使用することをお勧めします。

Azure AI 検索では、オートコンプリートされたクエリと検索候補結果は、suggester に登録する選択したフィールドからと検索インデックスから取得されます。 suggester はインデックスの一部であり、クエリを補完するか、結果を提示するか、その両方を行うコンテンツを提供するフィールドを指定します。 インデックスが作成されて読み込まれると、suggester のデータ構造が内部で作成され、部分的なクエリに対する照合に使用されるプレフィックスが格納されます。 検索候補については、一意であるか、少なくとも反復しない適切なフィールドを選択することが、このエクスペリエンスにとって重要です。 詳細については、suggester の作成に関するページを参照してください。

この記事の残りの部分では、クエリとクライアント コードに注目します。 重要なポイントを示すために、JavaScript と C# を使用します。 REST API の例は、各操作を簡潔に表現するために使用されています。 エンドツーエンドのコード サンプルについては、「次のステップ」を参照してください。

要求の設定

要求の要素には、入力と並行した検索の API の 1 つ、部分クエリ、suggester が含まれます。 次のスクリプトでは、例としてオートコンプリート REST API を使用して、要求のコンポーネントを示します。

POST /indexes/myxboxgames/docs/autocomplete?search&api-version=2020-06-30
{
  "search": "minecraf",
  "suggesterName": "sg"
}

"suggesterName" には、用語または検索候補の補完に使用される、suggester に対応したフィールドが示されます。 特に検索候補の場合、フィールド リストは、一致する結果の中で明確な選択肢を提供するもので構成される必要があります。 コンピューター ゲームを販売するサイトの場合、このフィールドはゲーム タイトルになる場合があります。

"search" パラメーターでは、部分クエリを指定します。ここでは、文字が jQuery Autocomplete コントロールを介してクエリ要求に送られます。 上の例の "minecraf" は、コントロールによって渡される可能性のある内容を静的に表したものです。

この API で、部分クエリに長さの最小要件が適用されることはありません。そのため、1 文字だけにすることもできます。 ただし、jQuery Autocomplete では最小長が指定されます。 少なくとも 2 文字または 3 文字が一般的です。

一致するのは、入力文字列に含まれる用語の先頭です。 "the quick brown fox" の場合、オートコンプリートでも検索候補でも、"the"、"quick"、"brown"、または "fox" という部分的なバージョンで一致となりますが、"rown" または "ox" のような部分挿入辞では一致となりません。 さらに、一致ごとにダウンストリーム拡張のスコープが設定されます。 部分クエリ "quick br" は "quick brown" または "quick bread" で一致となりますが、"brown" または "bread" 自体は、"quick" が前に付かない限り一致となりません。

入力と並行した検索の API

REST および .NET SDK のリファレンス ページについては、以下のリンク先を参照してください。

応答の構造化

オートコンプリートと検索候補の応答は、次のように、パターンに対して想定されるものです。オートコンプリートの場合は用語のリストが返され、検索候補の場合は用語とドキュメント ID が返されるため、ドキュメントを取得できます (特定のドキュメントの詳細ページを取得するには、Lookup Document API を使用します)。

応答が、要求のパラメーターによって形成されます。

  • オートコンプリートの場合は、autocompleteMode を設定して、テキスト補完が 1 つの用語で行われるか 2 つの用語で行われるかを指定します。

  • 検索候補の場合は、$select を設定して、一意または差別化の値 (名前や説明など) を含むフィールドを返します。 重複する値を含むフィールドは避けてください (カテゴリや市区町村など)。

次のパラメータは、オートコンプリートと検索候補の両方に適用されますが、特に suggester に複数のフィールドが含まれている場合は、検索候補により適しています。

パラメーター 使用法
searchFields クエリを特定のフィールドに制限します。
$filter 結果セットに一致条件を適用します ($filter=Category eq 'ActionAdventure')。
$top 結果を特定の数に制限します ($top=5)。

ユーザー操作コードの追加

クエリ用語をオートフィルするか、一致するリンクの一覧をドロップダウンするには、ユーザー操作コード (通常は JavaScript) が必要です。これにより、Azure Search のコグニティブ インデックスに対するオートコンプリートや検索候補クエリなど、外部ソースからの要求を使用できます。

このコードをネイティブに記述することもできますが、次のいずれかのように、既存の JavaScript ライブラリの関数を使用する方が簡単です。

  • オートコンプリート ウィジェット (jQuery UI) が検索候補コード スニペットに表示されます。 検索ボックスを作成した後、Autocomplete ウィジェットを使用する JavaScript 関数内でそれを参照することができます。 このウィジェットのプロパティでは、ソース (オートコンプリートまたは検索候補の関数)、操作が行われるまでの最小入力文字数、配置を設定します。

  • XDSoft Autocomplete プラグインがオートコンプリート コード スニペットに表示されます。

  • 検索候補JavaScript チュートリアルとコード サンプルに表示されます。

これらのライブラリをクライアントで使用して、検索候補とオートコンプリートの両方をサポートする検索ボックスを作成します。 検索ボックスで収集された入力を、検索サービスで検索およびオートコンプリート アクションとペアにすることができます。

推奨事項

このセクションでは、検索ボックスの定義から始めて、候補となる結果の実装について説明します。 また、この記事で参照されている 1 つ目の JavaScript オートコンプリート ライブラリを呼び出す方法とスクリプトについても紹介します。

jQuery UI Autocomplete ライブラリと C# の MVC プロジェクトを想定した場合、Index.cshtml ファイルで JavaScript を使用して、検索ボックスを定義できます。 このライブラリでは、MVC コントローラーに対する非同期呼び出しを実行して検索候補を取得することで、入力と並行した検索操作が検索ボックスに追加されます。

\Views\Home フォルダーにある Index.cshtml では、検索ボックスを作成する行は次のようになる場合があります。

<input class="searchBox" type="text" id="searchbox1" placeholder="search">

この例は、スタイリング用のクラス、JavaScript によって参照される ID、およびプレースホルダー テキストがあるシンプルな入力テキスト ボックスです。

同じファイル内で、この検索ボックスを参照する JavaScript を埋め込みます。 次の関数は、検索候補 API を呼び出します。この API は、部分的な用語入力に基づいて一致する候補ドキュメントを要求します。

$(function () {
    $("#searchbox1").autocomplete({
        source: "/home/suggest?highlights=false&fuzzy=false&",
        minLength: 3,
        position: {
            my: "left top",
            at: "left-23 bottom+10"
        }
    });
});

source では、検索ボックスの下に表示する項目の一覧を取得する場所を jQuery UI Autocomplete 関数に指示します。 このプロジェクトは、MVC プロジェクトであるため、クエリ候補を返すためのロジックを含む HomeController.cs 内で Suggest 関数を呼び出します。 また、この関数は、強調表示、あいまい一致、および用語を制御するためのいくつかのパラメーターを渡します。 オートコンプリート JavaScript API では、term パラメーターが追加されます。

minLength: 3 により、検索ボックスに 3 文字以上が入力されている場合のみ、検索候補が表示されます。

あいまい一致の有効化

あいまい検索では、ユーザーが検索ボックスに単語を間違って入力した場合でも、類似する一致に基づいて結果を取得できます。 編集距離は 1 です。これは、ユーザー入力と一致との間に最大 1 文字の不一致がある可能性があることを意味します。

source: "/home/suggest?highlights=false&fuzzy=true&",

強調表示の有効化

強調表示では、結果内で入力に対応する文字にフォント スタイルが適用されます。 たとえば、部分入力が "micro" の場合、その結果が microsoft、microscope などと表示されます。 強調表示は、HighlightPreTag パラメーターと HighlightPostTag パラメーターに基づき、Suggestion 関数でインラインで定義されています。

source: "/home/suggest?highlights=true&fuzzy=true&",

Suggest 関数

C# と MVC アプリケーションを使用している場合は、Controllers ディレクトリにある HomeController.cs ファイルで、候補の結果用のクラスを作成できます。 .NET では、Suggest 関数は SuggestAsync メソッドに基づいています。 .NET SDK の詳細については、「 .NET アプリケーションから Azure AI Search を使用する方法」を参照してください。

InitSearch メソッドは、認証された HTTP インデックス クライアントを Azure AI Search Serviceに作成します。 SuggestOptions クラスのプロパティによって、結果で検索され返されるフィールド、一致の数、およびあいまい一致を使用するかどうかが決まります。

オートコンプリートの場合、あいまい一致は 1 つの編集距離に制限されます (1 つの文字が省略されているか間違っています)。 オートコンプリート クエリであいまい一致が発生した場合、インデックスのサイズとそのシャード化方法に応じて、予期しない結果が生じることがあります。 詳細については、パーティションとシャード化の概念に関するページをご覧ください。

public async Task<ActionResult> SuggestAsync(bool highlights, bool fuzzy, string term)
{
    InitSearch();

    var options = new SuggestOptions()
    {
        UseFuzzyMatching = fuzzy,
        Size = 8,
    };

    if (highlights)
    {
        options.HighlightPreTag = "<b>";
        options.HighlightPostTag = "</b>";
    }

    // Only one suggester can be specified per index.
    // The suggester for the Hotels index enables autocomplete/suggestions on the HotelName field only.
    // During indexing, HotelNames are indexed in patterns that support autocomplete and suggested results.
    var suggestResult = await _searchClient.SuggestAsync<Hotel>(term, "sg", options).ConfigureAwait(false);

    // Convert the suggest query results to a list that can be displayed in the client.
    List<string> suggestions = suggestResult.Value.Results.Select(x => x.Text).ToList();

    // Return the list of suggestions.
    return new JsonResult(suggestions);
}

SuggestAsync 関数は、ヒットの強調表示が返されるかどうか、および入力された検索用語に加えてあいまい一致も使用するかどうかを決定する 2 つのパラメーターを使用します。 提案された結果には、最大 8 つの一致を含めることができます。 このメソッドは、Suggest API に渡される SuggestOptions オブジェクトを作成します。 結果は、クライアントに表示できるように JSON に変換されます。

オートコンプリート

ここまでは、検索候補の中核として、検索 UX コードを使用してきました。 次のコード ブロックは、XDSoft jQuery UI オートコンプリート関数を使用して、Azure AI Search オートコンプリートの要求を渡すオートコンプリートを示しています。 検索候補と同様に、C# アプリケーションでも、ユーザー操作をサポートするコードは index.cshtml にあります。

$(function () {
    // using modified jQuery Autocomplete plugin v1.2.8 https://xdsoft.net/jqplugins/autocomplete/
    // $.autocomplete -> $.autocompleteInline
    $("#searchbox1").autocompleteInline({
        appendMethod: "replace",
        source: [
            function (text, add) {
                if (!text) {
                    return;
                }

                $.getJSON("/home/autocomplete?term=" + text, function (data) {
                    if (data && data.length > 0) {
                        currentSuggestion2 = data[0];
                        add(data);
                    }
                });
            }
        ]
    });

    // complete on TAB and clear on ESC
    $("#searchbox1").keydown(function (evt) {
        if (evt.keyCode === 9 /* TAB */ && currentSuggestion2) {
            $("#searchbox1").val(currentSuggestion2);
            return false;
        } else if (evt.keyCode === 27 /* ESC */) {
            currentSuggestion2 = "";
            $("#searchbox1").val("");
        }
    });
});

Autocomplete 関数

Autocomplete は、AutocompleteAsync メソッドに基づいています。 検索候補と同様に、このコード ブロックは HomeController.cs ファイル内にあります。

public async Task<ActionResult> AutoCompleteAsync(string term)
{
    InitSearch();

    // Setup the autocomplete parameters.
    var ap = new AutocompleteOptions()
    {
        Mode = AutocompleteMode.OneTermWithContext,
        Size = 6
    };
    var autocompleteResult = await _searchClient.AutocompleteAsync(term, "sg", ap).ConfigureAwait(false);

    // Convert the autocompleteResult results to a list that can be displayed in the client.
    List<string> autocomplete = autocompleteResult.Value.Results.Select(x => x.Text).ToList();

    return new JsonResult(autocomplete);
}

Autocomplete 関数は、検索用語の入力を取得します。 このメソッドは、AutoCompleteParameters オブジェクトを作成します。 結果は、クライアントに表示できるように JSON に変換されます。

次のステップ

次のチュートリアルでは、入力と並行した検索のエクスペリエンスを示します。