Upgrade to Pro — share decks privately, control downloads, hide ads and more …

elasticsearch で作るランキング

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for iwagami iwagami
June 27, 2016

elasticsearch で作るランキング

Avatar for iwagami

iwagami

June 27, 2016
Tweet

More Decks by iwagami

Other Decks in Programming

Transcript

  1. スクリプト • 検索、更新、取得時にスクリプト(groovy 等) でな んでもできる • Scripting • 言語:groovyなど

    ◦ Ruby っぽい ◦ 他にも lucence script, native(Java) ◦ import して Java の関数呼んだりできる
  2. 作り方:例 • apache ログを時間で aggregation ◦ 重い… • バッチで1時間ごとに計算 ◦

    秘伝の技術になりがち • 1時間ごとの増減値(配列)をドキュメントに持たせ る (今日のお話) •
  3. データ構造 • お気に入り数の配列とその時刻(時)の配列 time_array: [ 160624T16, 160624T15, 160624T10, 160624T08 ...

    ] fav_array: [160624T16's fav数, 160624T15's fav数, 160624T10's fav数, …, 160624T08's fav数, ... ]
  4. スクリプトと検索クエリ fav_array=doc['fav_array'].values; time_array=doc['time_array'].values; // from, to はパラメータで来ます。 from〜to to =

    new DateTime().getMillis; from = to - 24時間前; sum = 0; for (i=0; i<fav_array.length; i++) { if (from < time_array[i] && time_array[i] < to) sum += fav_array[i]; } return sum; { "fuction_score":{ "query":{ "term”: { “category":”ゲーム” }, "functions":{ "script_score":{ "script":"fav_array=doc['fav_array']. values; ... " } } } } }
  5. フィルタを使ってスクリプト実行を減らす • デフォルト ◦ 全ドキュメントに対して スクリプトが実行され る→重い • フィルタ ◦

    script_scoreにはフィ ルタを付けれる ◦ フィルタされた要素だ けスクリプトを実行す "fuction_score":{ "functions":{ "filter":{ "exists":"fav_array" }, "script_score":{ "script":"fav_array=doc['fav_array'].values; ... " } } }
  6. スクリプト中では絶対 doc を使う • doc は fielddata 、ヒープにキャッシュされる ◦ 設定で制御できるらしいがデフォルトで使っている

    • _fields, _source も使えるがインデックスから読ん でくるので遅い ◦ ドキュメントでも使うなって言ってる • ただ doc は制限多い ◦ オブジェクトが使えない、number or string のみ
  7. 更新のスクリプト if(ctx._source['fav_array']==null || ctx._source['time_array']) = ... now = new DateTime().getMillis()/3600;

    if (ctx._source.time_array[0] == now) { ctx._source.fav_array[0] += 1; } else { ctx._source.time_array.add(0, now); ctx._source.fav_array[0].add(0, 1); }
  8. コンフリクトを気にしない • ESはドキュメント単位でのロック • 正直大雑把だけどめちゃくちゃ楽… • コンフリクトした場合→ retry • バズった時大変なことにならないのか?

    ◦ ESへのメッセージはすべてその前にキューで直列化して いるのでほぼコンフリクトは発生しない ◦ 遅延は発生するが。。。