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
見せてもらおうか、 OpenSearchの性能とやらを!
Search
shunta ichikawa
March 19, 2026
Programming
350
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
見せてもらおうか、 OpenSearchの性能とやらを!
shunta ichikawa
March 19, 2026
More Decks by shunta ichikawa
See All by shunta ichikawa
メンテが命: PHPフレームワークのコンテナ化とアップグレード戦略
shunta27
0
780
20240711_RAGを用いたシンプルな 社内情報検索システムを導入した話とつらみ
shunta27
2
5.6k
Other Decks in Programming
See All in Programming
源内ハンズオン概要編
hideg
0
190
React本体のコードリーディング
high_g_engineer
1
150
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
590
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
120
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
3.1k
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
710
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
640
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
460
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
520
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
700
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
690
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
230
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Designing Powerful Visuals for Engaging Learning
tmiket
1
490
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
370
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.1k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
800
Building Adaptive Systems
keathley
44
3.2k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
Into the Great Unknown - MozCon
thekraken
41
2.7k
Code Review Best Practice
trishagee
74
20k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.4k
Transcript
PHPerKaigi 2026
自己紹介 市川 俊太 いちかわ しゅんた (39歳) 株式会社助太刀 開発本部 開発部長 CTO
• 猫が好き • 趣味はサッカー観戦、ポケカ • Ruby/PHPなどのLL言語が好き
工事会社の人手不足を マッチング と正社員採用 で解決 会社紹介 受注者と発注者をつなぐ ビジネスマッチングサービス 建設業経験者向けの 求人サービス
OpenSearchとは • オープンソースの検索エンジン ◦ 2021年にAWSがElasticsearchをフォークして開発 ◦ ダッシュボード機能も存在(OpenSearch Dashboards) ◦ ドキュメント指向データベース
• 主な用途 ◦ 検索機能 ◦ ログ検索・分析 ◦ データ分析・ダッシュボード
Index / Document • Index = データの集合 • Document =
1件のデータ RDB OpenSearch Database Cluster Table Index Row Document Column Field Primary Key _id 基本構造(RDB / OpenSearch) Document Index
検索エンジンの仕組み(転置インデックス) 文書群から「単語」をキーにして「出現する文書IDや位置」を高速に検索するための索引構造 ID 職種 1 型枠大工 2 内装大工 3 型枠職人
単語 ID 型枠 [1, 3] 大工 [1, 2] 内装 [2] RDB OpenSearch LIKE '%型枠%' → 全件チェック 型枠 → [1, 3]
検索クエリの違い 「北海道で、型枠の仕事に関係する候補者を探す」 OpenSearchクエリ SQL
助太刀はマッチングプラットフォーム 🤝 主な検索機能 • 取引先検索 ◦ 例:職人さんを探す • 求人検索 ◦
例:建設会社の正社員求人を探す • 求職者検索 ◦ 例:企業が職人をスカウト ユーザ体験は「検索」から始まる
助太刀はマッチングプラットフォーム 🤝 主な検索機能 • 取引先検索 ◦ 例:職人さんを探す • 求人検索 ◦
例:建設会社の正社員求人を探す • 求職者検索 ◦ 例:企業が職人をスカウト (当時)検索機能は RDB(MySQL)を利用
結果 Laravelリクエストレイテンシ 約3秒 → 約500ms に改善
検索機能が抱えていた問題 • 検索条件の増加でSQLが巨大化 • Indexが効きづらい検索条件 ◦ LIKE / OR /
多段JOINなど • ページング用のCOUNTクエリが非常に重い → 結果として検索処理が遅い(平均3秒以上) SELECT … FROM candidates LEFT JOIN ... LEFT JOIN ... LEFT JOIN … WHERE speciality LIKE '%型枠%' OR ...
サービス展開の拡大 • Web版の提供 • ログイン前でも検索できるように変更 ◦ 検索流入・検索回数の増加 → 上記の施策が進行... 検索トラフィック増加!
サービス展開の拡大 • Web版の提供 • ログイン前でも検索できるように変更 ◦ 検索流入・検索回数の増加 → 上記の施策が進行... 検索トラフィック増加!
検索基盤としてOpenSearchを導入 • 提供しているサービスは Laravel で構築 • 検索機能は Eloquent を通して MySQL
を利用 Laravel / Eloquent と共存しながら 検索エンジンを OpenSearch に置き換え
OpenSearch と RDB を組み合わせた検索処理フロー OpenSearch RDB 1. 検索クエリ 2. ID一覧
3. Eloquent問い合わせ 4. レコード取得 検索サービス 北海道で、型枠の仕事に 関係する候補者を検索 検索はOpenSearch、正しいデータはRDB
OpenSearch と RDB を組み合わせた検索処理フロー
検索用データをOpenSearchに同期する OpenSearch RDB id name birth area speciality 123 市川工業
1987-02-07 北海道 型枠大工 Usersテーブル 同期 職種 Usersインデックス { "hits": { "hits": [ { "_id": "123", "_source": { "name": "市川工業", "area": "北海道", "speciality": "型枠大工" } }, …… ] } }
Laravel → OpenSearch OpenSearch RDB 1. 検索クエリ 2. ID一覧 3.
Eloquent問い合わせ 4. レコード取得 検索サービス
Laravel → OpenSearch Composerライブラリを利用 公式クライアント:opensearch-project/opensearch-php DSLクエリビルダー:shyim/opensearch-php-dsl
SQL検索をOpenSearchで表現する { "query": { "bool": { "must": [ { "wildcard":
{ "speciality": "*型枠*" } } ], "filter": [ { "term": { "area": "北海道" } } ] } }, "size": 10, "from": 0 } SELECT * FROM users WHERE speciality LIKE '%型枠%' AND area = '北海道' LIMIT 10 OFFSET 0; 1. SQL 2.OpenSearch DSL 3. クライアント実装
OpenSearch DSLをクエリビルダーライブラリで書く 3. クライアント実装 4. DSLライブラリ実装
DSLクエリービルダーライブラリを使う利点 • タイポ・構造ミスを防げる ◦ オブジェクトなら構造が保証される ▪ 配列だと must / filter
の入れ子を間違え やすい • 条件を動的に追加しやすい ◦ $query->add() のように積み上げられる ▪ 配列だとマージ処理が複雑 • IDE補完が効く ◦ クラス・メソッドが補完される 4. DSLライブラリ実装
Laravel → RDB OpenSearch RDB 1. 検索クエリ 2. ID一覧 3.
Eloquent問い合わせ 4. レコード取得 検索サービス
OpenSearchはID検索だけに使う OpenSearchの検索結果に含まれるID(_id)を 使ってEloquentで再取得する 検索結果のレスポンス構造 RDB id name birth area speciality
123 市川工業 1987-02-07 北海道 型枠大工 Usersテーブル 職種 同じIDで同期
OpenSearchはID検索だけに使う OpenSearchの検索結果に含まれる ID(_id)を使ってEloquentで再取得する 検索結果のレスポンス構造 • keyBy('id') で ID をキーにしたコレクションに 変換
• OpenSearch の並び順に合わせて map() で並び替える IDで再取得
• データの一貫性 ◦ OpenSearchはMySQLのレプリカで更新ラグがあるため、 Eloquentで再取得し最新データを保証。 • Eloquentのエコシステムをそのまま利用 ◦ OpenSearchのレスポンスは配列でありモデルマッピングが必要だが、 Eloquentで再取得すること
でリレーション・スコープ・アクセサなどの Laravel機能を利用可能。 • OpenSearchのスキーマを最小限に ◦ 検索に必要なフィールドのみ OpenSearchに持たせ、インデックスのメンテコストを削減。 • 責務が明確 ◦ OpenSearch:検索条件に合うIDリストを返す(全文検索、フィルタ、スコアリング) ◦ RDB (MySQL):そのIDに紐づくユーザーデータを返す(プロフィール、リレーションなど) OpenSearchをID検索だけに使うメリット
OpenSearchをID検索だけに使うデメリット • データストアに2回アクセスによるオーバーヘッド増大 • データ同期のタイミングによる不整合が発生しうる ◦ OpenSearch と RDB のデータが一時的に一致しないことがある
まとめ OpenSearchで検索性能は大きく改善できた Laravelと共存する現実的な移行もできた
OpenSearchで検索性能は大きく改善できた Laravelと共存する現実的な移行もできた でも、性能改善だけでは事業KPIは伸びなかった まとめ
OpenSearchで検索性能は大きく改善できた Laravelと共存する現実的な移行もできた でも、性能改善だけでは事業KPIは伸びなかった だからこそ、 技術課題と事業課題を切り分けて考えることが大事 まとめ
皆様、ご清聴ありがとうございました!