Azure HorizonDBでBM25 full-text searchがPublic Previewになったことで、PostgreSQL互換データベース内でBM25による全文検索を実行しやすくなりました。結論から言えば、商品コード、エラーコード、社内用語、文書名のような「入力されたキーワードそのもの」を重視する検索を、外部検索基盤へデータ同期せずにHorizonDB側で扱えるようになる点が大きな変化です。
一方で、これはPublic Previewの機能です。すぐに本番システムを置き換えるというより、既存のtsvector検索、Azure AI Search、Elasticsearch、Solr、ベクトル検索基盤と比較しながら、検索品質・レイテンシ・運用負荷を検証する段階と考えるのが現実的です。Azure Updatesのステータス定義でも、In previewは非本番用途での利用とテストを前提にした状態と説明されています。(Microsoft Azure)
Azure HorizonDBのBM25 full-text searchで何が変わるのか
今回のポイントは、Azure HorizonDBでpg_textsearch拡張機能を使い、BM25ランキング付きの全文検索をPostgres内で実行できるようになったことです。Microsoft Learnでは、pg_textsearchがAzure HorizonDBにBM25-ranked full-text searchを追加し、BM25はElasticsearch、Solr、Azure AI Searchでも使われる関連度ランキングアルゴリズムだと説明されています。(Microsoft Learn)
これまでPostgreSQL系の全文検索では、組み込みのtsvectorとGINインデックスを使う設計が一般的でした。しかし、検索結果の順位付けを本格的に改善したい場合、外部の検索エンジンを併用する構成になりがちです。BM25 full-text search in Azure HorizonDBでは、検索対象データの近くでBM25検索を実行できるため、検索インデックス同期、データ二重管理、アプリケーション側での結果結合といった複雑さを減らせる可能性があります。
特に影響が大きいのは、RAG、社内文書検索、ECの商品検索、サポートナレッジ検索、ログ・障害対応検索のように、キーワード検索とベクトル検索の両方が必要になりやすい領域です。HorizonDBのドキュメントでは、BM25は正確な語句、商品コード、エラーコード、固有名詞などに強く、ベクトル検索は同義語や言い換え、意味的な近さに強いと整理されています。(Microsoft Learn)
BM25とは何かを実務目線で理解する
BM25は、検索キーワードと文書の一致度を計算し、関連度の高い順に結果を並べるためのランキング手法です。単に「キーワードが何回出たか」だけで順位を決めるのではなく、文書の長さや語の珍しさも考慮します。
Microsoft Learnでは、BM25がts_rankでは扱えない課題として、キーワードの出現回数が増えるほど効果が頭打ちになる「term frequency saturation」、短い文書と長い文書の差を補正する「document length normalization」、一般的な語を下げ珍しい語を上げる「IDF」を挙げています。(Microsoft Learn)
実務では、これが検索品質に直結します。たとえば「PG-4012 connection timeout」という障害コードを検索した場合、ベクトル検索だけでは未知のコードをうまく拾えないことがあります。一方、BM25ならPG-4012のような識別子を強い手がかりとして扱えます。
| 検索方式 | 得意な検索 | 苦手な検索 | 向いている場面 |
|---|---|---|---|
| BM25全文検索 | 商品コード、エラーコード、固有名詞、正確なキーワード一致 | 言い換え、曖昧な質問、意味的な近さ | FAQ、商品検索、ログ検索、社内文書検索 |
| ベクトル検索 | 同義語、自然文質問、意味的な類似 | 型番、ID、略語、未知の専門用語 | RAG、レコメンド、ナレッジ検索 |
| ハイブリッド検索 | キーワード精度と意味検索の両立 | クエリとインデックス設計が複雑になりやすい | 本番想定のAI検索、サポート検索、企業内RAG |
対象者は誰か
BM25 full-text search in Azure HorizonDBのPublic Previewで確認すべき対象者は、主に次のような役割です。
| 対象者 | 確認すべきこと |
|---|---|
| Azure管理者 | HorizonDBの利用リージョン、Preview機能の利用可否、パラメーターグループ、拡張機能の許可設定 |
| DBA | 既存のPostgreSQL全文検索との違い、インデックス作成タイミング、更新負荷、クエリ計画 |
| アプリ開発者 | <@>演算子、to_bm25query()、スコアの扱い、検索APIのレスポンス設計 |
| RAG開発者 | BM25、pgvector、DiskANN、RRF、必要に応じた再ランキングの組み合わせ |
| 検索基盤担当者 | Azure AI SearchやElasticsearchを残すか、HorizonDB内検索へ寄せるかの判断 |
HorizonDB自体は、Microsoftが提供する次世代のクラウドネイティブなPostgreSQL互換サービスとして説明されており、AI機能や読み取りスケールアウト、エンタープライズ向けセキュリティを特徴としています。ただし、利用可能なAzureリージョンはPreview期間中に限られるため、検証前に対象リージョンを確認する必要があります。(Microsoft Azure)
既存のPostgreSQL全文検索との違い
pg_textsearchは、PostgreSQL標準のtsvectorとGINインデックスを完全に置き換えるものではありません。Microsoft Learnでも、PostgreSQLの組み込み全文検索は引き続き有効な選択肢であり、小規模な検索やts_rankで十分なワークロードでは既存方式でもよいと説明されています。(Microsoft Learn)
違いを実務的に整理すると、次のようになります。
| 比較項目 | tsvector + GIN | pg_textsearch + BM25 |
|---|---|---|
| 主な目的 | PostgreSQL標準の全文検索 | BM25による関連度順のTop-k検索 |
| ランキング | ts_rank | BM25 |
| インデックス対象 | tsvector列や式 | 通常のtext列を直接対象にできる |
| クエリの考え方 | WHERE @@ tsqueryで絞り込み | ORDER BY ... <@> ... LIMIT nで上位件数を取得 |
| 向いている用途 | 小規模検索、既存PostgreSQL標準機能で足りる検索 | 検索順位の品質が重要なキーワード検索 |
pg_textsearchでは、bm25というカスタムインデックスアクセスメソッドを使います。通常のtext列を直接インデックス化し、BM25ランキングは<@>演算子で取得します。Top-k検索ではORDER BY ... LIMIT nを使う設計が基本です。(Microsoft Learn)
管理者が確認すべき設定
BM25 full-text searchを使うには、pg_textsearch拡張機能を有効化する必要があります。Microsoft Learnでは、まずパラメーターグループを設定し、その後、各データベースで拡張機能を作成する流れが示されています。具体的には、shared_preload_librariesにpg_textsearchを含め、azure.extensionsにもpg_textsearchを含め、対象サーバーへパラメーターグループを適用したうえで、各データベースでCREATE EXTENSIONを実行します。(Microsoft Learn)
検証環境では、まず次の観点を確認してください。
| 確認項目 | 見るべきポイント |
|---|---|
| 利用リージョン | HorizonDBとPreview機能が対象リージョンで使えるか |
| パラメーターグループ | shared_preload_librariesとazure.extensionsにpg_textsearchを設定できるか |
| 再起動影響 | パラメーター適用時に再起動やメンテナンス時間が必要になるか |
| データベース単位の有効化 | 対象DBごとにCREATE EXTENSION IF NOT EXISTS pg_textsearch;を実行しているか |
| 権限管理 | 拡張機能作成やインデックス作成に必要な権限を誰が持つか |
| IaC反映 | Terraform、Bicep、CI/CDのDB初期化スクリプトに設定を入れるか |
設定後は、次のように値を確認できます。
SHOW shared_preload_libraries;
SHOW azure.extensions;
データベースごとの有効化は、次のように実行します。
CREATE EXTENSION IF NOT EXISTS pg_textsearch;
注意したいのは、拡張機能を「サーバー側で許可すること」と「各データベースで作成すること」は別の作業だという点です。開発環境では動いたのに検証環境で動かない場合、対象DBでCREATE EXTENSIONが実行されていない、またはパラメーターグループが別サーバーにだけ適用されている、といったミスが起きがちです。
開発者が押さえるべき基本的な使い方
BM25インデックスは、検索対象のテキスト列に対して作成します。Microsoft Learnの例では、USING bm25でインデックスを作成し、text_configで検索設定を指定しています。(Microsoft Learn)
CREATE INDEX idx_products_bm25
ON products
USING bm25 (description)
WITH (text_config = 'english');
検索は、ORDER BYでBM25スコアを使い、LIMITで上位件数を返すのが基本です。
SELECT id, name, description
FROM products
ORDER BY description <@> 'wireless noise cancelling headphones'
LIMIT 10;
ここで注意したいのは、<@>が返すBM25スコアは負の値で、値が小さいほど良い一致とされる点です。検索APIでスコアを画面表示したり、しきい値判定に使ったりする場合は、「大きいほど良い」と誤解しないように設計してください。(Microsoft Learn)
複数のBM25インデックスがあるテーブルや、ストアドプロシージャ内で使う場合は、to_bm25query()で対象インデックスを明示すると運用上の曖昧さを減らせます。Microsoft Learnでも、環境差や複数インデックスがある場合の一貫性を高める方法として明示的なインデックス指定が紹介されています。(Microsoft Learn)
SELECT id, name, description
FROM products
ORDER BY description <@> to_bm25query(
'wireless headphones',
'idx_products_bm25'
)
LIMIT 10;
日本語・多言語データで注意すべきこと
pg_textsearchは、text_configインデックスオプションを通じてPostgreSQLのテキスト検索設定を使います。Microsoft Learnでは、英語向けのenglishや、ステミングを行わないsimpleの例が示されています。(Microsoft Learn)
日本語の社内文書、FAQ、製品マニュアルを対象にする場合は、英語データと同じ感覚で設定すると期待した検索品質にならない可能性があります。日本語は単語の区切りが空白で明確に分かれないため、検索用テキストの整形方針を先に決めることが重要です。
実務では、少なくとも次の3点を検証してください。
| 確認項目 | 実務上の判断基準 |
|---|---|
text_config | SELECT cfgname FROM pg_ts_config;で利用可能な設定を確認する |
| 検索用テキスト | 日本語文書をそのまま入れるか、アプリ側で分かち書き・キーワード抽出済み列を用意するか |
| 検索ログ | 実際の検索語で、期待した文書が上位に出るかを評価する |
たとえば、問い合わせ文が「VPNにつながらない」で、文書側が「リモートアクセス接続エラー」と書かれている場合、BM25だけでは上位に出ないことがあります。この場合はベクトル検索とのハイブリッド検索を検討すべきです。一方、「ERR-2026」「SKU-AZ-009」「契約更新申請書」のような正確な文字列は、BM25が得意な領域です。
ベクトル検索やRAGと組み合わせるべきケース
BM25 full-text search in Azure HorizonDBは、単独でも使えますが、RAGやAI検索ではpgvector、DiskANN、RRFと組み合わせる価値が高くなります。HorizonDBのハイブリッド検索ドキュメントでは、BM25でキーワード一致の上位候補を取得し、pgvectorとDiskANNで意味的に近い候補を取得し、RRFで1つのランキングに統合する流れが説明されています。(Microsoft Learn)
ハイブリッド検索が有効なのは、次のような検索です。
| 検索例 | BM25が拾うもの | ベクトル検索が拾うもの |
|---|---|---|
PG-4012 connection timeout | PG-4012、connection、timeout | ネットワーク切断、DB応答遅延などの関連説明 |
請求書 再発行 | 請求書、再発行という語 | 「領収書をもう一度出したい」などの言い換え |
Azure VPN エラー 809 | 製品名、エラー番号 | VPN接続失敗に関する近い事象 |
退職時 PC 返却 | 退職、PC、返却 | オフボーディング手順、貸与端末回収 |
RRFは、BM25とベクトル検索のスコアを直接足し合わせるのではなく、それぞれの順位を使って統合する方法です。BM25スコアとコサイン類似度のようにスケールが違う値を扱う場合、順位ベースで統合できる点が実装上のメリットになります。Microsoft Learnでも、RRFは各ランカーの生スコアではなく順位を使うと説明されています。(Microsoft Learn)
既存システムから移行する場合の判断基準
既にAzure AI Search、Elasticsearch、Solrなどを使っている場合、BM25 full-text search in Azure HorizonDBが出たからといって、すぐに置き換える必要はありません。移行判断では、検索機能そのものだけでなく、取り込み、分析、運用、監視、権限管理まで含めて比較する必要があります。
| 現在の構成 | 移行・併用の考え方 |
|---|---|
PostgreSQLのtsvectorで小規模検索 | 検索順位に不満がある場合、pg_textsearchを検証する価値が高い |
| Azure AI SearchでRAGを構築済み | インデクサー、スキルセット、セマンティックランカー、外部データ連携を使っているなら慎重に比較 |
| Elasticsearch/Solrで高度な検索UIを提供 | ファセット、サジェスト、同義語、分析器、運用機能をどこまで使っているか確認 |
| アプリ側でDB検索とベクトル検索を別々に実行 | HorizonDB内のハイブリッド検索で同期ずれや結合処理を減らせるか検証 |
| 新規RAGアプリを設計中 | 最初からBM25、pgvector、DiskANNを同じDB内で試す価値がある |
置き換えやすいのは、「外部検索エンジンをBM25的なキーワードランキングのためだけに使っており、インデクサーや高度な検索UI機能には大きく依存していない」ケースです。逆に、ファセット検索、サジェスト、スペル補正、複雑な同義語辞書、複数データソースの取り込みなどを外部検索サービスに任せている場合は、HorizonDB内検索だけで同等の体験を作れるかを細かく検証してください。
展開前に確認したいパフォーマンス設計
BM25検索は、インデックスを作れば終わりではありません。検索対象列、クエリパターン、LIMIT件数、フィルター条件、データ更新頻度によって体感性能が変わります。
Microsoft Learnでは、Top-k検索の主要パターンとしてORDER BY ... LIMITを使うこと、バルクロード後にインデックスを作成すること、適切なtext_configを選ぶこと、大量ロード後にbm25_force_merge()を使うことでクエリ速度改善が期待できることが説明されています。(Microsoft Learn)
検証時は、次のような観点で測定しましょう。
| 観点 | 確認方法 |
|---|---|
| 検索レイテンシ | よく使われる検索語、長い検索語、ヒットしない検索語で測る |
| 上位結果の品質 | 検索ログ上位100件程度で、人手評価用の正解データを作る |
| インデックス作成時間 | 初期ロード後にインデックスを作る場合と、更新しながら作る場合を比較 |
| 更新負荷 | INSERT/UPDATEが多いテーブルで検索性能と書き込み性能を測る |
| フィルター併用 | テナントID、カテゴリ、日付範囲などの条件付き検索を試す |
| スコアしきい値 | <@>のスコアを使う場合、固定値ではなく検索ログから調整する |
よくある失敗は、開発環境の少量データで「速い」と判断してしまうことです。BM25の検索品質は文書集合全体の語の出現頻度に影響されます。少量データでは上位に出た文書が、本番相当のデータ量では下がることもあります。評価用データは、最低でも実運用に近いカテゴリ分布、文書長、重複文書、ノイズを含めて用意するべきです。
Public Previewで特に注意したい制限
Preview段階の機能は、仕様や制限が変わる可能性があります。現時点のMicrosoft Learnでは、pg_textsearchの制限として、ネイティブなフレーズクエリがないこと、組み込みの曖昧検索・タイプミス対応演算子がないこと、PL/pgSQLでは明示的なインデックス名が必要なことが説明されています。(Microsoft Learn)
| 制限・注意点 | 影響 | 対応案 |
|---|---|---|
| ネイティブなフレーズクエリがない | "Azure VPN"のような語順を厳密に見る検索が苦手 | BM25で候補取得後、アプリ側やSQLで後処理する |
| 組み込みの曖昧検索・ typo演算子がない | 入力ミスに弱い | 必要に応じてpg_trgmなどPostgreSQL側の機能を検討 |
| PL/pgSQLでは明示的なインデックス名が必要 | ストアドプロシージャで暗黙指定が動かない可能性 | to_bm25query(query, index_name)を使う |
| Preview機能である | 本番採用の判断に慎重さが必要 | 非本番で評価し、変更履歴を追跡する |
| 言語設定の選定が必要 | 日本語検索で期待通りに分割されない可能性 | 検索用テキスト列や前処理を検討する |
この制限を見落とすと、「検索結果の順位は良くなったが、完全一致フレーズやタイプミス対応で既存検索より劣る」という評価になりかねません。BM25は万能な検索機能ではなく、関連度順のキーワード検索を強化するための基盤として見るのが適切です。
導入検証の進め方
BM25 full-text search in Azure HorizonDBを検証するなら、いきなり全検索を置き換えるのではなく、検索ログを使って小さく始めるのがおすすめです。
| ステップ | 実施内容 | 成果物 |
|---|---|---|
| 検索ログの整理 | 実際に使われている検索語を集める | 評価クエリ一覧 |
| 対象テーブル選定 | FAQ、商品、文書チャンクなど1領域に絞る | 検証用スキーマ |
| BM25インデックス作成 | 検索対象列にUSING bm25でインデックスを作る | 検索SQL |
| 既存検索との比較 | tsvector、Azure AI Search、ベクトル検索と比較 | 上位結果の比較表 |
| ハイブリッド検索検証 | BM25 + pgvector + RRFを試す | RAG向け検索クエリ |
| 運用観点の確認 | インデックス作成時間、更新負荷、権限、再起動影響を確認 | 展開判断メモ |
評価では、単に「ヒット件数が多いか」ではなく、上位5件または上位10件に欲しい結果が入っているかを見てください。検索画面やRAGでは、20件目に正解があってもユーザー体験は改善しません。BM25の価値は、欲しい文書を上位に持ってくることにあります。
まとめ:まずは「正確なキーワード検索」が効く領域から試す
BM25 full-text search in Azure HorizonDBは、Azure HorizonDB内でBM25による全文検索を実行できるPublic Preview機能です。PostgreSQL互換データベース内で、検索対象データとBM25検索を近くに置けるため、外部検索インデックスへの同期やアプリケーション側の結合処理を減らせる可能性があります。
ただし、Previewであること、ネイティブなフレーズ検索や組み込みの曖昧検索には制限があること、日本語検索ではtext_configや検索用テキスト設計の検証が必要なことは押さえておくべきです。
次に取るべき行動は明確です。まず、実際の検索ログから「コード、型番、固有名詞、エラー番号、文書名」が多い領域を1つ選び、非本番のAzure HorizonDB環境でpg_textsearchを有効化します。そのうえで、既存検索、BM25単独、BM25 + ベクトル検索の3パターンを比較してください。検索結果の上位品質と運用負荷の両方でメリットが確認できた領域から、段階的に展開するのが安全です。

コメント