Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
mimiのElasticsearch活用例/mimi-es
Search
yazaki_r
September 19, 2017
Programming
3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
mimiのElasticsearch活用例/mimi-es
yazaki_r
September 19, 2017
Other Decks in Programming
See All in Programming
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
19
19k
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
130
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
350
Verilogで学ぶCPU自作入門.pdf
uyuki234
7
3.8k
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
250
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
5k
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2k
Are APIs Still Relevant in the AI Era?
soyuka
0
370
SREの越境 / SRE Collaboration
y0hgi
2
290
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
260
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
170
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
190
Featured
See All Featured
Faster Mobile Websites
deanohume
310
32k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
290
My Coaching Mixtape
mlcsv
0
330
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
710
Mind Mapping
helmedeiros
1
380
Music & Morning Musume
bryan
48
7.4k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
710
HDC tutorial
michielstock
2
920
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
380
Google's AI Overviews - The New Search
badams
0
1.6k
Transcript
mimiのElasticsearch活用事例 2017.09.11 yazaki_r@mimiLab
自己紹介 氏名:矢崎亮太 所属:株式会社mimiLab 役割:PM 兼 サーバサイドエンジニア
今日話すこと ・mimiの紹介・検索機能 ・Why Elasticsearch? ・インデックス再構築事例 ・今後やりたいこと ・検索事例
mimi とは? 好きなタイプ(顔)で検索できるマッチングアプリ 24時間/365日の監視体制 身分証明書による年齢確認 独自の顔認証システム 2016年12月リリース 好きなタイプ(顔)で検索できる! 【特徴】
機能紹介:タイプ検索(1) 好きなタイプ(顔)で検索できる! 【プリセットされたタイプ例】 ・キレイ系/可愛い系女子 ・ショートカット女子 ・メガネ女子 ・高身長/低身長女子 ・スレンダー/グラマー女子 ・金髪/黒髪女子 などなど。
※女性で登録すれば男性も検索可能です。
機能紹介:タイプ検索(2) 【設定可能条件】 ・年齢 ・居住地 ・加工画像排除 ・目/鼻/口/眉など ・髪型/髪色/体型/肌の色など ・メガネ/八重歯/鎖骨など カスタムタイプで検索条件を細かくできる! 【設定例】
・年齢:18 - 22歳 ・居住地:東京 AND 神奈川 ・加工画像排除ON ・目:奥二重 ・髪型:ロング ・髪色:黒髪 ・その他:八重歯 他にもマニアックな設定が色々できるよ!
機能紹介:タイプ検索(3) 男女で検索項目が違う! 男性の検索画面 【男性の設定項目】 ・塩顔/しょうゆ顔/ソース顔 ・ウマ顔/ネコ顔/サル顔/ヘビ顔 ・ヒゲ有/無 など 【女性の設定項目】 ・キレイ系/カワイイ系 ・黒髪/金髪
・泣きボクロ/えくぼ/うなじ など 女性の検索画面
機能紹介:リスト検索 一覧からも検索できる! 【設定可能条件】 ・年齢 ・居住地 ・加工画像排除 ・年収/職業/血液型など ・趣味・よく行く場所など ・タバコ/お酒の頻度など ・結婚の意思/デート費用など
・登録日/最終ログイン日など
特徴:豊富な検索機能 カスタム検索 【設定可能条件】 ・年齢 ・居住地 ・加工画像排除 ・目/鼻/口/眉など ・髪型/髪色/体型/肌の色など ・メガネ/八重歯/鎖骨など }
} 完全一致 スコアマッチ ※一致している人だけ出したい ※一致している順で出したい 基本条件 見た目条件
それゆえ要件が多い 【機能要件一部】 ・男女で検索項目が異なるのでそれぞれ検索したい ・一部項目は完全一致で検索したい(居住地など) ・さらに年齢などは範囲検索したい ・見た目条件など条件一致率が高いものから順に表示したい ・「いいね」か「イマイチ」した相手は表示しない などなど ※他にもユーザーの属性 /状態によって優先表示する内容や並び順を変えたりしています。
Why Elasticsearch? ・検索機能が豊富! - 見た目条件など条件一致率の高い順に表示したい場合、Elasticsearchの _scoreフィールドが役立ちそう。 ・高パフォーマンス! - 表示するアルゴリズム上、幾つかの条件を検索/計算する必要があるた め、MySQLなどではレスポンスタイムを担保できない。
- クエリを何度も投げずに目的の検索機能を実現できそう。
構成 EC2 ELB Aurora(Master) Aurora(Slave) ×n台 ×n台 検索機能要件を満たすために検索に関わるデータのみElasticsearchに格納している VPC Internet
Gateway Redis Elasticsearch
検索事例
検索事例 ・基本的にスコア付けはboolクエリを応用{ "mimi_matching": { "mappings": { "appearance_female": { "properties": {
"academic_career": { "type": "long" }, Must クエリ{ And条件。 filterと違いスコアが計算される。 Should クエリ Or条件。 filterと違いスコアが計算される。 Filter クエリ And条件。 スコアが計算されない。
検索事例 【要件】 ・男女で検索項目が異なるのでそれぞれ検索したい curl -XGET 'http://******/mimi_index/_mapping?pretty' { "mimi_index": { "mappings":
{ "appearance_female": { "properties": { "academic_career": { "type": "long" }, …… curl -XGET 'http://******/mimi_index/_mapping?pretty' { "mimi_index": { "mappings": { "appearance_male": { "properties": { "academic_career": { "type": "long" }, …… →男女でtypeを分ける 男性用 女性用
検索事例 【要件】 ・一部項目は完全一致で検索したい(居住地など)/ 年齢などは範囲検索したい(1) "mimi_index": { "mappings": { "appearance_male": {
"properties": { "living_place": { "type": "long" }, "age": { "type": "long" }, //// 以下略 →居住地は居住地ID(long)を、年齢も数値(long)を保存。 マッピング 居住地(living_place):東京(ID:1) 年齢(age):20歳 “fields”:{ "living_place": 1, "age": 20, } ※居住地IDは仮 保存内容例 保存内容例
検索事例 【要件】 ・一部項目は完全一致で検索したい(居住地など)/ 年齢などは範囲検索したい(2) →bool クエリでmust/range検索 "query": { "bool":{"must":[ {"range":
{"age":{"gte":18,"lte":22}} }, {"terms": {"living_place":[1,2]} }]} } クエリ例 居住地(living_place):東京or神奈川 年齢(age):18歳以上22歳以下 クエリ例 WHERE (`age` >= 18 AND `age` <= 22 ) AND `living_place` IN (1,2); MySQLだとこんな感じ
検索事例 【要件】 ・さらに見た目条件は一致率が高いものから順に表示したい(2) "mimi_index": { "mappings": { "appearance_male": { "properties":
{ "eye": { "type": "long" }, "hair_color": { "type": "long" }, //// 以下略 →見た目マスタID(long)を保存。 マッピング 目(eye):ぱっちり二重(ID:1) 髪の色(hair_color):黒髪(ID:1) “fields”:{ "eye": 1, "hair_color": 1, } ※見た目の各IDは仮 保存内容例 保存内容例
検索事例 【要件】 ・さらに見た目条件は一致率が高いものから順に表示したい(2) →bool クエリでshouldでterms検索、_scoreでソート "query": { "bool":{"should":[ {"terms": {"eye":[1,2]}},
{"terms": {"hair_color":[1,2]}} ] }, "sort":[ {"_score":"desc"} ] クエリ 目(eye):ぱっちり二重 , 奥二重 髪の色(hair_color):黒髪 , 茶髪 クエリ例 実現できない! MySqlだと、、、
検索事例 【要件】 ・「いいね」か「イマイチ」した相手は表示しない →bool クエリでmust_notで非表示対象を指定 "query": { "bool":{"must_not":[ {"terms": {"_id":["*******","**********"]
}} ]}} クエリ 非表示対象はRedis など別領域に保存
インデックス再構築事例
インデックス定義やシャーディングの設定は、 作成時に決められるため、 すでに決められたタイプなどの再定義はできない。 そのため、切り替え方法を工夫する必要がある。 インデックス再構築事例
インデックス再構築事例 リスト画面が重い → Elasticsearchで検索したい 【設定可能条件】 ・年齢 ・居住地 ・加工画像排除 ・年収/職業/血液型など ・趣味・よく行く場所など ・タバコ/お酒の頻度など ・結婚の意思/デート費用など
・登録日/最終ログイン日など 元々ここはMySQLで検索する想定だっ たため、Elasticsearchの検索フィールド には何も入っていなかった。
インデックス再構築事例 - 問題点 【設定可能条件】 ・年収/職業/血液型など ・趣味・よく行く場所など ・タバコ/お酒の頻度など ・結婚の意思/デート費用など ElasticSearch には格納されていない
フィールド多数ある 【設定可能条件】 ・登録日/最終ログイン日 たまたま登録されていたが、 フィールドのtype が 想定と違う "created": { "type": "string" }, インデックス再定義が必要
インデックス再構築事例 - やること (1)別インデックス再構築 (2)再構築したインデックスへの切り替え (案1)ES側でエイリアスを作成して切り替える (案2)アプリケーション側で調整して切り替える インデックス定義やシャーディングの設定は、作成時に決められるため、 すでに決められたタイプなどの再定義はできない。 そのため、切り替え方法を工夫する必要がある。
インデックス再構築事例 - インデックス再定義実行 ・別インデックスを作成 / 足りないフィールドを追加したマッピングを作成{ "mimi_matching": { "mappings": {
"appearance_female": { "properties": { "academic_career": { "type": "long" }, "mimi_index_v2": { "mappings": { "appearance_male": { "properties": { "blood_type": { "type": "long" }, "create_time": { "type": "date", "format": "yyyy-mm-dd HH:mm:ss" }, "last_login_time": { "type": "date", "format": "yyyy-mm-dd HH:mm:ss" }, マッピング 登録時間(create_time):2017-08-30 11:00:00 ログイン時間(last_login_time):2017-08-30 11:00:00 保存内容例
インデックス再構築事例 -(案1)エイリアスを作成して切り替える Application ・現状 mimi_index mimi_index_new インデックス 旧インデックス 新インデックス
Application エイリアス ・エイリアスを作成する mimi_index mimi_index mimi_index_new インデックス 旧インデックス 新インデックス インデックス再構築事例
-(案1)エイリアスを作成して切り替える
Application エイリアス ・re_index API でドキュメントをコピー mimi_index mimi_index mimi_index_new インデックス re_index
旧インデックス 新インデックス インデックス再構築事例 -(案1)エイリアスを作成して切り替える
Application エイリアス ・ mimi_index mimi_index mimi_index_new インデックス 旧インデックス 新インデックス ・
エイリアスの付け先を変更する インデックス再構築事例 -(案1)エイリアスを作成して切り替える
インデックス再構築事例 -(案1)エイリアスを作成して切り替える ・元々同期していないMySQL上のデータは? ・サービス稼働中にドキュメントコピーできるの? ・切り替え後、切り戻しはどうやる? (古いインデックスには古いデータしかない) 疑問点
インデックス再構築事例 - (案2)アプリケーション側で調整する Application ・現状 mimi_index mimi_index_new インデックス 旧インデックス 新インデックス
インデックス再構築事例 - (案2)アプリケーション側で調整する Application ・ mimi_index mimi_index_new インデックス 旧インデックス 新インデックス
INSERT/SELECT INSERT only ・更新/参照は旧インデックス、新インデックスにも更新を行うようにする
Application 同期ツール SELECT データ同期 ・同期ツールを作成して新インデックスへデータ同期{ ※MySQLテーブルを正にして新インデックスへ同期するツールを作った ※ESはあくまで検索のためだけに使う想定なので、同期元(マスタ)はMySQLテーブルのデータにしている mimi_index_new インデックス再構築事例 -
(案2)アプリケーション側で調整する INSERT only mimi_index_old INSERT/SELECT INSERT/SELECT
Application mimi_index mimi_index_new インデックス 旧インデックス 新インデックス INSERT/SELECT INSERT only ・アプリケーションで接続先切り替え
更新/参照は新インデックス、旧インデックスにも更新を行うようにする インデックス再構築事例 - (案2)アプリケーション側で調整する
インデックス再構築事例 - (案2)アプリケーション側で調整する ・元々同期していないMySQL上のデータは? →同期ツールで解決 ・サービス稼働中にドキュメントコピーできるの? →同期ツールで解決 (MySQLテーブルを正にして、アプリケーションとバッチの双方から書き込み) ・切り替え後、切り戻しはどうやる? (古いインデックスには古いデータしかない)
→古いインデックスにも書き込みを続けているので切り戻しOK 疑問点
インデックス再構築事例 - 結果 案2で対応。 エイリアスもre_indexAPIも使わずに インデックスの再構築(サービス無停止)を行いました。
今後やりたいこと(1) ・特定条件によってFunctionScore クエリで重み付けしたい "mappings": { "appearance_female": { "properties": { "academic_career":
{ "type": "long" }, "query": { "function_score": { "query": { "bool": { "should": [{ "term": {"eye":[1,2],}}]} }, "score_mode": "sum", "boost_mode": "multiply", "functions": [{{ "filter": { "term": { {"age":{"gte":25,"lte":29}}}}, "weight": 10 }, {"filter": { "term": { {"age":{"gte":20,"lte":24}} }}, "weight": 5 }, クエリ ユーザーによって年齢の近い順など 様々な条件で重み付け これにより様々な条件で ユーザーを並べ替えられる! マッチングサービスな のでコレ大事
今後やりたいこと(2) Parent-Childを使用して 非表示対象ユーザーを除外したい 【親ドキュメント】 【子ドキュメント】 除外対象
None
ご清聴ありがとうございました。 以上。