Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
elasticsearch で作るランキング
Search
iwagami
June 27, 2016
Programming
2.4k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
elasticsearch で作るランキング
iwagami
June 27, 2016
More Decks by iwagami
See All by iwagami
GCP_WORKSHOP_1_GCE
iwag
0
360
Introduction of finagle
iwag
1
170
Introduction of JAVA8
iwag
0
390
cocos2d-jsで雑に作るブラウザゲーム
iwag
0
270
Rewrite in Finagle
iwag
4
1.4k
Chisel RISC-V introduction
iwag
1
3.1k
Other Decks in Programming
See All in Programming
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
330
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
230
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.2k
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
6.6k
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
320
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
140
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
240
スマートグラスで並列バイブコーディング
hyshu
0
140
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
250
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
160
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
160
Featured
See All Featured
Un-Boring Meetings
codingconduct
0
310
Context Engineering - Making Every Token Count
addyosmani
9
960
GitHub's CSS Performance
jonrohan
1033
470k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
210
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Everyday Curiosity
cassininazir
0
230
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
200
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
590
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
Transcript
elasticsearchで ランキングを作ろう iwag 2016/06/27 elasticsearch勉強会 #16
誰よ • iwag • Scala/finagler/elasticsearch
スクリプト • 検索、更新、取得時にスクリプト(groovy 等) でな んでもできる • Scripting • 言語:groovyなど
◦ Ruby っぽい ◦ 他にも lucence script, native(Java) ◦ import して Java の関数呼んだりできる
更新 • insert, update ◦ リンク • ドキュメントの値(ctx._source) を読み書き加工
検索 • スコア計算 ◦ ドキュメントの値を読んでスコアを算出する • スクリプト付きフィルタ • 値の取得(スクリプトフィールド) ◦
ランキング
ランキングとは • 現在時刻から24時間のお気に入り増減数の順 • 1時間ごとに更新
作り方:例 • apache ログを時間で aggregation ◦ 重い… • バッチで1時間ごとに計算 ◦
秘伝の技術になりがち • 1時間ごとの増減値(配列)をドキュメントに持たせ る (今日のお話) •
データ構造 • お気に入り数の配列とその時刻(時)の配列 time_array: [ 160624T16, 160624T15, 160624T10, 160624T08 ...
] fav_array: [160624T16's fav数, 160624T15's fav数, 160624T10's fav数, …, 160624T08's fav数, ... ]
スクリプトと検索クエリ 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; ... " } } } } }
ヒント
スクリプトめっっっっちゃ重い • フィールド >>> プラグイン(Native) >>>>>>>>>>>>> スクリプト(groovy) • プラグイン ◦
結構簡単に作れる ◦ 更新に再起動がいるので今回は断念
フィルタを使ってスクリプト実行を減らす • デフォルト ◦ 全ドキュメントに対して スクリプトが実行され る→重い • フィルタ ◦
script_scoreにはフィ ルタを付けれる ◦ フィルタされた要素だ けスクリプトを実行す "fuction_score":{ "functions":{ "filter":{ "exists":"fav_array" }, "script_score":{ "script":"fav_array=doc['fav_array'].values; ... " } } }
スクリプト中では絶対 doc を使う • doc は fielddata 、ヒープにキャッシュされる ◦ 設定で制御できるらしいがデフォルトで使っている
• _fields, _source も使えるがインデックスから読ん でくるので遅い ◦ ドキュメントでも使うなって言ってる • ただ doc は制限多い ◦ オブジェクトが使えない、number or string のみ
更新
前提 • クリック時にスクリプト付き(+1) updateが飛ぶ
更新のスクリプト 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); }
ヒント
コンフリクトを気にしない • ESはドキュメント単位でのロック • 正直大雑把だけどめちゃくちゃ楽… • コンフリクトした場合→ retry • バズった時大変なことにならないのか?
◦ ESへのメッセージはすべてその前にキューで直列化して いるのでほぼコンフリクトは発生しない ◦ 遅延は発生するが。。。
パフォーマンス • 更新時のスクリプトはパフォーマンスを気にしなく て良い ◦ せいぜい更新1回 • スクリプトの計算よりインデックスへのストアのほ うが重い
古いデータどうするのか? • バッチで48時間以上前のデータは消している • クエリ付き update があるとうれしいなという要望
デバッグどうするのか • スクリプトでloggerが使える ◦ https://www.elastic.co/blog/elasticsearch-logging-secrets • デバッグ用フィールド ◦ スクリプト中で ctx._source.debug
= “....”;
まとめ
まとめ • elasticsearch のスクリプトの話をしました • ランキングの作り方を紹介しました • スクリプトを活用する上でのヒントを紹介しました
おまけ
ホットエントリ(みたいなもの) もつくれます • スクリプト付きフィルタを使う • 例 ◦ 直近1時間のお気入り数が10以上でフィルタ ◦ 適当に並べる
• あってるかは不明…