一昨日(10/17)ですが、「第25回Elasticsearch勉強会「検索編」 」というイベントに参加してきました。
今回は日本経済新聞社さんの主催ということで、会場は大手町の日経ホール&カンファレンスルームで行われました。 当日は少し早く出たこともあって、日本橋から大手町まで歩いてみました。 東西線で一駅と思って歩いたのですが、よくよく地図を見てみると日本橋の端から大手町の端までという感じで結構距離がありました。 素直に電車で行けばよかった(笑)
なんで参加したか
Elasticsearchを使った検索システム構築について、学んでおきたかったからです。 実はElasticsearchを使って検索システムを構築したことはあるのですが、インストールして検索できるようにしただけで、きちんと設計してインデックスを作ったり、検索クエリについて考えるということはできていませんでした。このままじゃ不味いな、と思ってはいたのですが、マニュアル読んでもちょっとピンとこないところもあり、勉強会で事例とかを聞いてみたいな、というのが参加の動機です。
参加してみて
当日の様子は、参加者の皆さんが積極的にツイッターで呟いていますので、ハッシュタグ #elasticsearchjp を追うと雰囲気がつかめると思います。
会場説明
最初に un Ohtani @ Elastic さんから会場についての説明。
これまでの参加者に対するアンケートの結果をグラフで解説されていました。 スライドは後でアップされる予定とのことです。
すでに次回の勉強会の募集も始まっているということで、紹介がありました。 テーマは「メトリック/ログ分析編」と、これまた聞きたい内容ですね。ということで早速僕も参加申し込みしました。
スピーカー募集もされているようですので、われこそはという方はぜひ。
メディアコンテンツ向け記事検索DBとして使うElasticsearch
最初は Future Architect 株式会社 村田 靖拓さん (twitter: @famipapamart) で「メディアコンテンツ向け記事検索DBとして使うElasticsearch」というタイトルでの発表でした。
スライドはアップされていないようなので、当日のメモから少し。
- 取り扱うコンテンツはニュース記事素材
- 記事は執筆中と過去に執筆されたものに別れる。
- フリーワード検索を頻繁にされる。
- 記事素材の親子関係を1インデックスに収める。
- 文字列のtypeは文字列型を使うかkeyword型を使うか、検討が必要。
- 日付検索は必ずしも範囲検索にならない(yyyy年mm月の記事、など)ので文字列型にしてワイルドカード検索もできるように考慮した。
- 異体字の展開はcharactor filterを利用して行った。
- elastic searchで標準的に使えるプラグインで実現
- Dynamic field mappingを有効にしている。
- 項目の定義変更を考慮してobject型で切った領域を用意しておいた。
- パフォーマンスはQueryとfrom(offset値)に依存する
- 初回QueryのQueryLatency速度の担保が難しい。
- max_result_windowの壁
- デフォルト値だと10000。100万件以上ヒットする記事の検索をするには?
- パラメータを変えれば変更は可能だが、速度に影響する。(メモリには大きな影響はない)
- from値が大きくなればなるほどLatencyは上がっていった。
- 1indexあたりのデータ件数はなるべく小さくできると良い。
- インデックスを分割して1indexあたりのデータ件数を減らす。
- max_result_windowを超えるような場合は、Scroll APIの利用が望ましい。
- ただし、要件定義次第では from/size 指定に余流検索が必要になってしまう。
- データモデリングは非正規化 slideship.com
- Mapping定義 Dynamic field mapping利用時は注意が必要
記事検索の話ということで非常に興味深く聞きました。 インデックスの分割や検索結果件数のところは、以前に悩んだことがあるのでとても参考になりました。
minne での検索海鮮の歴史
2番めは @_shiro16 さん で「minne での検索改善の歴史」というタイトルでの発表でした。
スライドはこちら。
以下、当日取ったメモ。
- 初期
- SolrからESへ。
- 1期
- Found(Elastic Cloud)を使った
- 辞書が使えない
- スケール大変
- Found(Elastic Cloud)を使った
- 2期
- 自前でEC2上に構築
- AWSのESはESのバージョンが古い
- 辞書が使えない
- 自前でEC2上に構築
- 検索結果の良し悪し
- ユーザーが求めているものを検索できているか?
- minneでは行動ログを使って計測
- 行動ログをTDに入れて、それをre:Dashなどで検索
- A/Bテスト結果も集計
- キャンペーン時などにブレるので注意が必要
- ログを蓄積するメリット
- 昨年のログを見てトレンドを知ることができる
- FunctionScoreQueryを使い、スコアを変更
- Completion suggester
- オートコンプリート
- ES5まではエンドポイントがあったがES6では通常の検索APIにSuggester用のクエリを投げる
- サジェスト用の単語はどうするか?
- 行動ログから抽出して反映
- 類義語辞書も作成
- 登録は手動なので割と辛い
- ハンドメイド業界の用語を知らないといけないので難しい
- 辞書はpuppetで管理
- 集計してAnalyzeかけて反映を回す(ただし手動)
@_shiro16 さんの参加報告エントリを書かれていたので、リンクを貼っておきます。
AWSのESを採用しなかった理由の話は、採用してツラミを味わった身としては「ですよねー」という気持ち。 サジェストの話や辞書登録の話は運用には欠かせない要素なので、参考になりました。 専門養母や略語は難しいですね、やっぱり。
query_stringのはなし / 加藤遼さん (日本経済新聞社)
最後は 加藤遼さん (日本経済新聞社) で「query_stringのはなし」というタイトルでの発表。
スライド speakerdeck.com
当日取ったメモ。
- 日経電子版の検索システムは ES+Djangoで構築
- 記事のメタデータ フィールド200以上
- 会社名、カテゴリ、タイプ等を保持
- 検索のAND/ORが結構複雑
- 検索結果は再現性を優先するためにスコアではなく時系列を優先している
- 検索対象とキーワードを入れてマッチするものを検索(match string)
- 検索キーワードを直接検索文字列にかける(query_string)
- query string query
- default fieldパラメータ
- 指定したフィールドを検索対象にする
- 指定がない場合はすべてのフィールドを検索するので注意が必要
- default fieldパラメータ
- query stringパラメータはバージョンによって結構変わるので注意が必要
- パラメータによって生成されるクエリが大きく変わるのでdescriptionを確認
- fieldは指定
- 複雑なクエリ使い放題なのでパフォーマンスなどに注意
- simple query string
- 記述ミスがあってもエラーが発生しない
- 使える指定がシンプルになっている。
- 指定する語がキーワードになるので注意
- query stringのパースルールではORが優先される
- OR > AND > NOT で優先される
matchとquwry_stringをあまりわからず使っていましたが、発表を聞いてすごくスッキリしました。 仕様がバージョンによって変わるとか結構怖い話もありましたが、使いこなせれば強力な武器になりますね。 (本番システムに組み込むとかではなく、開発時や研究環境などで)
まとめ
今回は体調が悪くて懇親会には参加できませんでしたが、発表者の方に色々聞けたら良かったな、と思いました。 会場からの質問タイムは結構皆さんガチな質問が多くてちょっと手を挙げられなかったので、、、
発表内容は非常に実践的で参考になるものばかりでしたし、参加者も熱心に聞き入っていて熱気あふれる現協会だなと思いました。 次回も申し込んだので、また参加できることを楽しみにしています。