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
mimiのElasticsearch活用例/mimi-es
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
5.2k
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
250
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
140
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
840
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
8.8k
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.7k
Webフレームワークの ベンチマークについて
yusukebe
0
200
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
480
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
260
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
2
810
Featured
See All Featured
Leo the Paperboy
mayatellez
8
1.9k
Into the Great Unknown - MozCon
thekraken
41
2.6k
WENDY [Excerpt]
tessaabrams
11
38k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
630
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
600
A Modern Web Designer's Workflow
chriscoyier
698
190k
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Embracing the Ebb and Flow
colly
88
5.1k
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
ご清聴ありがとうございました。 以上。