Fessの近接検索で単語の距離を指定する

Fessで"word1 word2"~Nという近接検索の指定を、実際の検索クエリに反映するようにしました。フレーズの間に別の単語が入っていても探せるため、完全一致では取りこぼしてしまう文書を見つける際に役立ちます。

フレーズ検索との違い

通常のフレーズ検索は、解析後の単語が連続する条件で検索します。

"quick fox"

近接検索では、フレーズの後ろに~と数値を付けます。

"quick fox"~1

例えば単純に単語ごとの位置が付く場合、quick brown foxのように間に1語入った文も対象になります。タイトルなどフィールドを指定した検索にも使えます。

title:"quick fox"~2

従来はパーサーが距離の値を保持していても、検索エンジンへ渡すmatch_phraseクエリに反映していませんでした。今回、通常フィールド、指定フィールド、未知のフィールドからのフォールバックに距離を渡し、ハイライトのクエリにも反映します。

距離は文字数ではない

Nが数えるのは、フィールドのアナライザーが生成したトークンの位置です。英語ではおおむね単語間の距離になりますが、除去されたストップワードも位置を占めます。単語の順序を入れ替えた一致にも距離が必要です。

日本語では、一般のタイトル・本文フィールドでCJK bigram、言語別フィールドで形態素解析を使うなど、解析方法によって距離の意味が変わります。単純に「N文字以内」と読み替えることはできません。

"全文 検索"~5
"大阪 おいしい"~10

日本語で複数の語の近さを指定する場合も、語を空白で区切ります。つなげた文字列を指定すると、意図した単語間の近接検索にならない場合があります。少し広めの距離から始め、実際の結果を見ながら絞り込んでください。

どんな検索に向いているか

「運用」と「手順」のように関係する語が同じ箇所に現れる文書を探したいときに使えます。AND検索では離れた場所にある語も一致し、完全なフレーズ検索では間に語が入った文書を落としてしまうので、その中間の条件として利用できます。

近接検索の説明ページもFess 15.9のドキュメントに追加しました。実際のアナライザーによる違いを踏まえて距離を調整するのがポイントです。

関連PR

FessのAIチャットで1つの文書について質問する

FessのAIチャットに、検索結果から選んだ1つの文書を対象に質問する機能を追加しました。複数の検索結果を横断して回答する通常のチャットに加え、「この手順書の要点を教えて」「この資料の条件を説明して」といった使い方ができます。

検索結果から文書チャットを開く

AIチャットが有効な場合、標準のbootstrapテーマでは検索結果に文書について質問するリンクが表示されます。リンクを開くと、対象文書のタイトルを示すバナーが現れ、その文書を参照して会話します。

バナーを解除するか新しいチャットを始めると、通常のチャットへ戻ります。別の文書に切り替えた場合も新しいセッションになります。

文書だけを参照する仕組み

POST /api/v2/chatとPOST /api/v2/chat/streamに、任意のdoc_idを追加しました。文書を指定した場合は検索や検索クエリの再生成を省略し、指定文書を回答の参照元にします。ラベルなどのfieldsやextra_queriesもこの経路では利用しません。

文書の取得には閲覧ロールの確認を適用します。存在しない文書と閲覧権限のない文書はいずれも404となります。チャットの有効・無効、ログイン条件、CSRF対策、ユーザー単位のレート制限も従来と同じです。

サーバーは対象文書の状態を保持しないので、独自クライアントでは会話の各リクエストにdoc_idを送る必要があります。

長い文書は分割して要約する

LLMのコンテキストに収まる文書は1回の呼び出しで回答します。長い文書は分割し、質問に関連する情報を各部分から要約した後、それらをまとめて回答します。

分割数の上限はfess_config.propertiesで指定できます。

rag.chat.document.max.parts=10

上限を超える文書では先頭の部分だけを利用し、ストリーミングAPIはdocument_truncatedの警告を通知します。非ストリーミングAPIには同じ警告を通知する経路がありません。

利用時の注意点

長い文書は質問のたびに要約し直します。標準の上限では部分要約に最大10回、回答生成に1回のLLM呼び出しが必要になるため、待ち時間や利用量を考慮してください。

また、長文の「翻訳」は部分要約から生成するため、全文の逐語的な翻訳にはなりません。対象を1つに絞ることで質問しやすくなりますが、LLMの回答は原文と照らし合わせて確認してください。

関連PR

Fess 15.9に向けたOpenSearchと既存インデックスの移行準備

Fess 15.9の開発版で、利用するOpenSearchが3.9.0へ更新されました。移行時には、OpenSearch本体とプラグインのバージョンを揃えることに加え、プラグインの取得先と既存の文書インデックスの扱いを確認する必要があります。

この記事は2026年10月4日時点でmainブランチへマージされた変更をもとにした移行準備のメモです。確認したFessの最新リリースは15.8.0で、15.9をリリース済みとして案内するものではありません。対応する開発版を検証する場合、または変更を含むリリースへの移行時に参照してください。

OpenSearchとプラグインを揃える

今回の開発版では、fess-setupの初期値が次のようになっています。

component.opensearch.version=3.9.0
component.opensearch.plugin.version=3.9.0
component.opensearch.plugin.repository=https://maven.codelibs.org/release

対応版のFessに同梱されたセットアップツールでは、次のコマンドでOpenSearchを導入します。

bin/fess-setup install opensearch

既存のOpenSearchへプラグインだけを導入する場合は、インストール先を指定します。

bin/fess-setup install opensearch-plugins --opensearch-home /path/to/opensearch-3.9.0

対象はanalysis-fess、analysis-extension、minhash、configsyncの4プラグインです。3.8.1以降のこれらの配布先はmaven.codelibs.orgです。手動でopensearch-pluginを使う場合、Maven座標形式はMaven Centralだけを参照するため、3.9.0のZIPのURLを指定します。例えばanalysis-fessは次のように導入します。

bin/opensearch-plugin install https://maven.codelibs.org/release/org/codelibs/opensearch/opensearch-analysis-fess/3.9.0/opensearch-analysis-fess-3.9.0.zip

残りの3プラグインも同じ配布先の3.9.0を使い、OpenSearch本体とバージョンを一致させます。公式OpenSearchバンドルにはk-NNが含まれています。独自に構成する場合も、15.9で必要となるk-NNを確認してください。Docker版は15.9.0-SNAPSHOTとOpenSearch 3.9.0の組み合わせへ更新されています。15.8.0の組み合わせはOpenSearch 3.8.0なので、既存の15.8環境へ新しいCompose定義をそのまま適用する前に対応関係を確認します。

既存インデックスへ新しい定義を反映する

15.9は起動時に設定・ログ・ユーザーのインデックスへ不足するフィールドを追加します。一方、文書インデックスのマッピングと解析設定は自動変更しません。15.8以前の文書インデックスでは、所有者・最終更新者の検索や、かなと長音記号の表記揺れの正規化を使うために再インデクシングが必要です。

管理画面の「システム情報」→「メンテナンス」で「エイリアスの更新」と「辞書の初期化」を有効にして、「再インデクシング」を実行します。既存文書を新しいインデックスへコピーする処理なので、マッピングと解析設定の反映だけなら再クロールは不要です。これらのチェックを初期状態のままにせず、実行前に確認してください。

「辞書の初期化」はOpenSearch側の辞書を同梱ファイルで上書きします。同義語などを独自に編集している場合は、事前にダウンロードし、再インデクシング後に必要な変更を反映し直します。

所有者の値を取得するには再クロールも必要

再インデクシングで定義を揃えても、以前に索引したファイルへ所有者の値が追加されるわけではありません。ファイルシステム・SMB・FTPの対象ファイルから値を取得するにはクロールが必要です。

差分クロールでは変更のないファイルを取得し直さないため、「システム」→「全般」の「最終更新日時の確認」を一時的に無効にしてクロールします。対象ファイルの取得が終わったら通常の差分クロール設定へ戻します。文書のコピーと、元ファイルから不足する値の取得を分けて考えると移行作業を整理できます。

切り戻し用のバックアップを残す

OpenSearch 3.9.0で取得したスナップショットは、3.8.0以前へ復元できません。切り戻しに使うアップグレード前のスナップショットと設定・辞書のバックアップを残しておきます。また、辞書はOpenSearchの設定ディレクトリ配下へ配置します。この制限は3.8.0からのものです。

新機能の設定だけでなく、プラグインの配布先、文書インデックスの再構築、必要に応じた再クロールまで含めて検証しておくと、15.9への移行を準備できます。

関連PR