これまでは Azure Search を使って様々な検索やフィルタリングを試してきましたが、今回は作成したインデックスを使ってオートコンプリートを実装してみました。
オートコンプリートを実装するためには入力された部分キーワードから候補一覧を取得する必要がありますが、Azure Search は Suggest API を持っているので、インデックスを作るときに SupportSuggestions メソッドを呼び出しておくだけで候補を取得できるようになります。
var client = new IndexManagementClient(connection); await client.CreateIndexAsync(new Index("entries") .WithStringField("id", p => p.IsKey().IsRetrievable()) .WithStringField("title", p => p.IsSearchable().IsRetrievable().SupportSuggestions()) .WithDateTimeField("createdOn", p => p.IsFilterable().IsSortable().IsRetrievable()) );
今回はこのブログのタイトル全てをインデックスに入れようと思っているので、シンプルに title フィールドだけ SupportSuggestions メソッドを追加しました。これも文字列や文字列のコレクション限定になります
そして入力候補を取得するためのコードはこんな感じです。
var client = new IndexQueryClient(connection); var result = await client.SuggestAsync("entries", new SuggestionQuery("Azure") .Top(10) );
SearchAsync ではなく SuggestAsync メソッドに書き換え、SuggestionQuery を渡すように変更しました。
この時点で実行してみると、Azure から始まるタイトルの候補が取得できました。
今回はオートコンプリートとして実装したいので、ちょっとめんどくさいですが ASP.NET アプリとして組み込みました。ちなみに Azure Search の API を叩くアクションは殆ど変っていません。
[HttpPost] public async Task<ActionResult> Suggest(string text, bool fuzzy) { var connection = ApiConnection.Create("shibayan", "KEY"); var client = new IndexQueryClient(connection); var result = await client.SuggestAsync("entries", new SuggestionQuery(text) .Fuzzy(fuzzy) .Top(10) ); if (!result.IsSuccess) { return HttpNotFound(); } return Json(result.Body.Records.Select(p => p.Text).ToArray()); }
fuzzy フラグはあいまい検索を行うかどうかです。SuggestionQuery は Fuzzy メソッドで true を指定することで、あいまい検索を有効にして候補一覧の取得が出来ます。
ビュー側も適当に作ったので、実際に候補一覧が出るか試してみました。
問題なく表示されましたね。次はあいまい検索を試してみます。
Windows を Widows と typo しても、Windows から始まるタイトルが候補として出力されました。
英語は問題なかったので、日本語も試してみました。ついでにあいまい検索も動作するのか確認します。
あいまい検索がどのような実装になっているかはわかりませんが、日本語であってもそれなりの精度であいまい検索は動作してくれるようです。