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
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
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
470
App Intentsのビルドプロセスを支える技術
kntkymt
0
250
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
110
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
390
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
130
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
150
GKE で Pod の見方を変えたら、スケールアウト時の挙動を真に捉えられた話
stkk
0
110
tsc.rip を支える技術 / Kyoto.なんか #8
susisu
0
4.4k
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.7k
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
160
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
Bash Introduction
62gerente
615
220k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
330
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
240
Evolving SEO for Evolving Search Engines
ryanjones
0
280
Being A Developer After 40
akosma
91
590k
Making Projects Easy
brettharned
120
6.7k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
700
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Embracing the Ebb and Flow
colly
88
5.2k
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
ご清聴ありがとうございました。 以上。