YASD-TECH
YASD TECH
# Rails

OpenSearchとActiveRecordの利用用途の違い

投稿日:2026/7/12

更新日:2026/7/22

ttitleImage

OpenSearch と ActiveRecord の利用用途の違いまとめ

検索エンジン(OpenSearch)と ORM(ActiveRecord)は役割が違う。どちらを使うか迷ったとき用の整理メモ。
関連: インデックスという用語の混同(RDB vs OpenSearch)(用語の整理)、
searchkickのレイヤー構造とOpenSearchからActiveRecordへの境界(Rails での実装の内側)


1. ざっくり結論

OpenSearch ActiveRecord (+ RDB)
正体 検索エンジン(Elasticsearch 系 OSS) ORM(背後は MySQL / PostgreSQL 等の RDB)
データの位置づけ 検索用の複製(インデックス) 正のデータ源(source of truth)
得意なこと 複雑な条件の高速な絞り込み・全文検索・スコアリング データの正確な永続化、トランザクション、関連(association)の取得
苦手なこと データの一貫性保証(複製なので古くなりうる) 全文検索、多条件の柔軟な組み合わせ検索(SQL が複雑化・低速化)
問い合わせ言語 Query DSL(JSON) SQL(ORM が生成)

検索機能では両方を役割分担で使うのが定石。
「誰(どのレコード)がヒットするか」を検索エンジンが決め、「その実データ」を ORM が RDB から取り出す。


2. どちらを使うか

2-1. ActiveRecord(RDB)が向くケース

  • CRUD(作成・参照・更新・削除)の基本操作
  • トランザクションが必要な処理(決済、ステータス遷移など)
  • 関連をたどる取得(user.posts のような association)
  • 「ID や外部キーで特定のレコードを引く」単純な検索
  • データの正確性・一貫性が最優先の場面

2-2. OpenSearch / Elasticsearch が向くケース

  • 全文検索(キーワードが本文のどこかに含まれる、形態素解析、あいまい一致)
  • 多条件の組み合わせ検索(条件グループを AND/OR/NOR で自由に組む検索 UI など)
  • ファセット / 集計(検索結果の件数内訳、絞り込みナビ)
  • スコアリング・ランキング(関連度順、function_score による重み付け)
  • 大量データに対する検索レイテンシの要求が厳しい場面

3. よくある組み合わせパターン

検索エンジンと RDB は「どちらか」ではなく、書き込みと読み込みで併用するのが一般的。

書き込み: アプリ → RDB(正データ)→ 検索エンジンへ同期(インデックス更新)
読み込み: 検索は検索エンジン → ヒット ID で RDB から実体を取得して表示
  • 検索エンジンは「検索に最適化した読み取り専用ビュー」として使い、正データは常に RDB に置く
  • 表示に使うデータを RDB から取り直すのは、インデックスが古い可能性があるため
    (検索結果の一覧性は多少古くても許容し、詳細データは正確に、という割り切り)

注意点

  • 同期遅延(Near Real-Time): 2つの要因で直後の検索に反映されないことがある。
    1. アプリ→検索エンジンの同期処理自体が非同期になりがち
    2. OpenSearch 自体が近リアルタイム(NRT)で、書き込みはリフレッシュ間隔(デフォルト1秒)を待って初めて検索対象になる
      → 同期的に保存したはずなのに直後の検索にヒットしない、という混乱はこのため
  • 二重管理: スキーマ変更時は DB マイグレーションとインデックス定義(mappings)の両方の更新が必要
  • 再インデックスコスト: マッピング変更は基本フル再インデックスになる
  • 検索エンジンを正データにしない: 消えても RDB から再構築できる状態を保つ

4. わかりやすい例え(図書館モデル)

役割分担を「巨大な図書館」に置き換えると直感的に理解できる。

4-1. 登場人物の対応

登場人物 図書館での役割 何をする人か
ActiveRecord (RDB) 書庫(本棚そのもの) 本物の本が並ぶ。正のデータ源。
OpenSearch 蔵書検索カタログ(索引カード) 「この条件の本はどの棚の何番か」を高速に返す。中身の複製ではなく“場所と目印”だけ持つ。
検索 API(GraphQL / REST) 受付カウンター 利用者の「こういう本ある?」を受け取り、裏で手配して返す窓口。

4-2. 本を探すときの流れ

利用者:「料理、和食、1990年以降、写真多め の本ある?」

受付(API)が要望を聞く

カタログ(OpenSearch)で該当する本の "整理番号" を一気に絞り込む
  → 「該当は 12冊、番号は A-3, B-7, C-1 …」(= WHERE 句の仕事)

その番号で 書庫(ActiveRecord)から本物の本を取ってくる
  → 表紙・目次・著者情報など“実データ”はここで初めて手に入る

受付が利用者に本を手渡す

4-3. なぜ2つに分けるのか(核心)

  • カタログ(索引)は探すのが速い。 何万冊あっても「和食かつ1990年以降かつ写真多め」を一瞬で絞れる。ただしカタログに本物の中身は載っていない。
  • 書庫(本棚)は中身が正確。 ただし条件で端から探すのは遅く大変(=複雑な SQL が遅くなる)。
  • だから 「どれが該当するか」はカタログに聞き、「その本の中身」は書庫から取る、と役割を割り切る。

4-4. 注意点も同じ例えで説明できる

  • 索引は古くなりうる → 新しく入った本がまだカタログ未反映のことがある(=インデックスの同期遅延)。だから最終的に手渡す本は必ず書庫の本物を取り直す。
  • 本を入れたらカタログも更新が要る → 二重管理(DB マイグレーション+インデックス定義)。
  • カタログが焼けても書庫があれば作り直せる → 検索エンジンを正データにしない。

4-5. 一言まとめ

OpenSearch は「目次・索引」、ActiveRecord は「本文そのもの」。
索引で当たりを付けて、本文を開いて確認する。人間が分厚い本を読むときと同じことを、システムがやっている。

4-6. 他の例え(好みで差し替え可)

  • 通販サイト:OpenSearch=商品検索・絞り込み(一覧はざっくり速く)、RDB=カートに入れて決済する時の正確な在庫・価格。
  • 地図アプリ:OpenSearch=「近くのカフェ」を条件で探すピン表示、RDB=店を選んだ後に出る営業時間・電話番号などの正データ。

Index

  • OpenSearch と ActiveRecord の利用用途の違いまとめ
  • 1. ざっくり結論
  • 2. どちらを使うか
  • 2-1. ActiveRecord(RDB)が向くケース
  • 2-2. OpenSearch / Elasticsearch が向くケース
  • 3. よくある組み合わせパターン
  • 注意点
  • 4. わかりやすい例え(図書館モデル)
  • 4-1. 登場人物の対応
  • 4-2. 本を探すときの流れ
  • 4-3. なぜ2つに分けるのか(核心)
  • 4-4. 注意点も同じ例えで説明できる
  • 4-5. 一言まとめ
  • 4-6. 他の例え(好みで差し替え可)