また Azure の新機能が色々と発表されましたが、個人的には Azure Search が特に気になったので使ってみることにしました。既に抱かれたい男 No.1 が触っているので、そっちも参照してください。
Azure Search ちょっとさわってみた « ブチザッキ
日本語周りの対応が個人的には気になったので、今回は自分のツイートログを Azure Search に突っ込んで検索するようなコードを書いて試しました。自然言語が満載なので、いい感じの確認が出来ると思います。
まだ公式には REST API しか公開されていないっぽいですが、RedDog.Search というライブラリがほぼ同時に公開されているので、これを使うことで比較的簡単に Azure Search の操作が行えました。
reddog-io/RedDog.Search · GitHub
とりあえずはプレビューポータルから Azure Search を作る必要があります。
作成されるまでにちょっと時間がかかるかもしれませんので、その間にサンプルアプリケーションを作成しておきます。と言っても、NuGet で RedDog.Search をインストールすれば環境は整います。
Azure Search に限らず検索系のサービスはインデックスを作らないと検索を行えないので、まずはインデックスを作成します。
// API へのアクセスに必要な情報 var connection = ApiConnection.Create("shibayan", "KEY"); // インデックスへの操作を行う場合に使う var client = new IndexManagementClient(connection); // tweets という名前で id, status, createdOn を持つインデックスを作成 await client.CreateIndexAsync(new Index("tweets") .WithStringField("id", p => p.IsKey().IsRetrievable()) .WithStringField("status", p => p.IsSearchable().IsRetrievable()) .WithDateTimeField("createdOn", p => p.IsRetrievable().IsSortable()) );
RedDog.Search は Fluent Interface を採用しているので、わかりやすく設定できます。インデックスのフィールド指定で使っているラムダ式では以下の拡張メソッドでフィールドの属性を指定できます。
- IsFacetable
- ファセットとして利用可能か
- IsFilterable
- フィルタリングが可能か
- IsKey
- キーとなる値か
- IsRetrievable
- 結果として返却を行うか
- IsSearchable
- 検索の対象か
- IsSortable
- ソートが可能か
わかりやすいメソッド名となっていますね。
これだけのコードでインデックスの作成が完了するので、次は実際にインデックスへデータをアップロードしていきたいと思います。
// IndexOperationType.Upload を指定するとインデックスへのデータ追加 var operation = new IndexOperation(IndexOperationType.Upload, "id", "1") .WithProperty("status", "抱かれたい男 No.1 とムッシュと TaaS") .WithProperty("createdOn", DateTimeOffset.Now); // データのアップロード await client.PopulateAsync("tweets", new[] { operation });
今回はわかりやすくするためにツイートが保存された CSV 周りの処理を削除して、実際にデータのアップロードを行うコードだけ紹介しました。
ちなみに Azure Search のポータルから確認できるインデックスの状態はこんな感じです。1000 ツイートをインデックス化したのでドキュメント数はちゃんと 1000 になっていますね。
これで検索を行う準備が出来たので、実際に Azure Search を使ってツイートの検索を行ってみます。
// 検索を行う場合は IndexQueryClient を使う var client = new IndexQueryClient(connection); // SearchQuery の引数が検索したい文字列、SearchField は検索対象のフィールド var result = await client.SearchAsync("tweets", new SearchQuery("抱かれたい男") .SearchField("status") .Top(10)); foreach (var item in result.Body.Records) { // Properties には IsRetrievable を呼び出したフィールドの値が入る Console.WriteLine("{0} - {1},{2},{3}", item.Score, item.Properties["id"], item.Properties["status"], item.Properties["createdOn"]);}
実行した結果は以下になります。パッと見は良い感じに日本語でも検索できている気がしますが、よく見ると検索キーワードが全く含まれていないツイートもヒットしていることがわかります。
どうやら日本語で検索する場合には、検索キーワードをダブルクオートで囲む必要がありそうです。
今度は検索キーワードをダブルクオートで囲んでから検索を行った結果です。
ちゃんとキーワードだけが含まれているツイートが返ってきました。
日本語もとりあえずは検索を行えるようで安心したので、面白そうな使い方も試してみたいと思います。