Fessのコード検索で引用語・ファイルリンク・Rust分類を見直す

Fessのコード検索で、引用符付きの単語にも曖昧検索が加わる問題、特殊文字入りのファイルへのリンク、Rustの言語分類を直すPRが提案されています。

単語を引用符で囲んだときの検索

通常の検索ではquery.boost.fuzzy.min.lengthの初期値4以上の長さの語に、暗黙の曖昧検索が加わります。PR #3670は、デフォルトフィールドの単語を引用符で囲んだ場合、1語のフレーズとして扱って、この曖昧検索を加えない修正です。新しい設定を有効化する手順はありません。

たとえばlessと「”less”」を比較します。PRでは、修正前の「”less”」でfessだけを含む文書もヒットした例が報告されています。修正後も解析器による正規化は受けるため、元ファイルとのバイト単位の完全一致を保証する検索ではありません。

引用符なしの語、content:”x”などのフィールド指定、複数語フレーズは今回の変更対象ではありません。allintitle/allinurlの1語フレーズには既存の制限が残り、デフォルトフィールドの「”fess*”」は従来の前方一致から文字列のフレーズ扱いへ変わる点にも注意します。

特殊文字入りのファイルと離れた行の表示

codesearchテーマのPR #86では「リポジトリで開く」リンクのパスを区切りごとにURLエンコードします。たとえばdir/a b#c%d.mdをdir/a%20b%23c%25d.mdへ変換し、#や?、%で別のファイルを開いてしまうことを避けます。リンク先は引き続き/blob/HEAD/で、検索時のコミットを固定する機能ではありません。

また、L3の断片とL42の断片が「…L42:」で連結されている場合、後者を別行と行番号で表示します。行番号が続かない通常の「…」は残します。文書の抽出方法を変える修正ではありません。

PRのテーマは15.10.1、最小Fessバージョンは15.10です。Fess 15.9へそのまま導入する説明にはしません。修正を含むソースで./scripts/package.sh codesearchを実行し、対応するFessの管理画面「テーマ」でZIPをアップロードして選択します。配布ZIPが公開済みとは確認していません。

Rustの分類は設定反映と再クロールが必要

docker-codesearchのPR #15はconf/fess_config.overlay.propertiesのindex.filetypeにapplication/rls-services+xml=rustを加える提案です。TikaがこのMIMEタイプと判定する.rsファイルを、従来のothersからrustへ分類し、言語ファセットとfiletype:rustで探せるようにします。本文抽出は変わりません。

既存の文書は再クロールするまでothersのままです。環境の実効設定にマッピングが反映されたことを確認してから対象リポジトリを再クロールし、filetype:rustで確認します。保存済み文書を移すだけの再インデックスで再分類されたとは判断しません。

以前のpath絞り込みとJavaScript・YAML分類の記事とは、検索の一致条件・結果リンク・Rust分類が今回の違いです。

関連PR

FessのPlaywrightクロールで動的ページの取得範囲と転送を確認する

FessでJavaScriptを使うページをクロールするとき、ブラウザで見える内容がすべて検索対象になるわけではありません。Playwrightクローラーは、取得時点のDOMをHTMLとして取り出し、その本文とリンクを処理します。待機を延ばせば解決する場合と、ページ側の構造を見直す必要がある場合を分けて確認します。

導入とNode.jsの確認

Fess 15.9以降ではPlaywrightクローラーを追加プラグインとして導入します。ZIP構成ではFessの配置先で次を実行し、Fessを再起動します。利用するFessと対応するプラグインの版をそろえてください。

bin/fess-setup install plugin fess-crawler-playwright
bin/fess-setup install nodejs

Webクロール設定のパラメーターで、対象URLにPlaywrightを割り当てます。例えばHTTPSの対象では次のように指定します。

client.crawlerClients=playwright:https://.*

プラグインのJava API・JavaScriptドライバーとは別に、実行用のNode.jsが必要です。自前のNode.jsを使う場合は、Fessを起動する環境のPLAYWRIGHT_NODEJS_PATHにその実行ファイルのパスを設定します。ブラウザは初回利用時にPlaywrightがダウンロードするため、取得先への通信と実行環境のOS依存ライブラリーも必要です。

PR #81はNode.js不足で初期化に失敗した場合に、上記の導入コマンドと環境変数を案内する提案です。ブラウザ起動など他の段階の失敗を自動修復する変更ではありません。ジョブの成功表示だけで判断せず、失敗URLとfess-crawler.log、検索に入った本文を確認してください。

取得するのは待機後のDOM

待機状態を決めるrenderedStateの初期値はNETWORKIDLE、その後に追加で待つcontentWaitDurationの初期値は0ミリ秒です。追加待機を設定する場合、例えば3000は3秒であり、初期値でも推奨値でもありません。サイトで本文が出る時刻に合わせて調整します。

ネットワークが落ち着いた後にタイマーで本文が追加されるページは、初期設定の取得時点に間に合わない場合があります。一方、追加待機だけで無限スクロールやボタン操作が実行されるわけではありません。

ページの仕組み取得範囲・制限
JavaScriptが通常のDOMへ追加した本文やリンク取得時点に存在すれば本文・リンクの処理対象
開いたShadow DOMの内部シリアライズした通常のDOMに含まれず、本文に入らない
iframeの内部外側のページの本文には入らない。srcは別ページとしてたどるため、URLフィルターなどの条件が適用される
スクロールで追加する一覧スクロール前に存在する内容まで
onclickだけで移動するボタンリンクとしてたどらない。hrefを持つリンクなど別の到達経路が必要
#/aboutなどフラグメントだけのリンク独立した文書として登録されない

この整理はPR #82の文書追加に基づきます。表の制限をすべて解消する新機能が入る、という提案ではありません。

自動転送と同じ転送先の重複を切り分ける

PR #80はlocation.replace()やmeta refreshでページ自身が移動した場合に、最初のページの応答本文を読もうとして失敗する問題への修正案です。最新のメインフレームの応答を使い、移動先のURLで登録するようにします。移動先にもURLフィルターが適用され、対象外への移動はクロール対象外として扱います。PRの説明によれば15.9.0にも同じ問題があります。

転送が取得待機の終了後に発生する場合は、元のページの状態を取得することがあります。contentWaitDurationはこの待機時間の調整に使えますが、あらゆるタイミングの転送を保証するものではありません。

別のPRであるfess-crawler #227は、複数の旧URLが同じページへ転送される際の[CONFLICT] Failed to insertを扱います。ブラウザ側で転送を追跡し、要求URLと応答URLが異なり、redirectLocationがなく、同じクロールセッションで転送先のアクセス結果が保存済みの場合、その応答の処理をスキップしてINFOログへ記録する提案です。初回の転送先や通常の同一URLの応答は対象外で、新しい設定スイッチもありません。アクセス結果の保存済み確認なので、並行実行を含むすべての重複を防ぐ保証ではありません。

動作確認では、通常の動的本文、自動転送、対象外への転送、遅延転送、同じ転送先へ集まる複数URLを分けて試し、検索結果のURL・本文と失敗URLを照合します。本記事では実環境での再検証は行っておらず、PRの説明・差分・テストと公式ソースを確認しています。採用版が配布された後、適用されたプラグインとクローラーの両方を確認してください。

関連PR

既存のPlaywrightを利用したクロールは導入の背景、Fess 15.9.0の移行チェックは配布構成を扱っています。今回は動的ページの取得範囲と失敗の切り分けに絞っています。

Fessの画像検索で本文に入れるメタデータを絞る

画像をFessで検索すると、説明やキーワードのほかに、ピクセル数、圧縮方式、カラープロファイルなどの値が本文へ並ぶことがありました。15.10向け開発ブランチでは、画像の本文へ追加するメタデータを、タイトルや説明などの項目に絞る変更がマージされています。

画像の本文に追加する項目を選ぶ

MIMEタイプがimage/で始まる文書には、新しいcrawler.metadata.content.image.includesが適用されます。値はカンマ区切りの正規表現で、メタデータ名全体への一致を判定します。初期値は次のとおりです。

crawler.metadata.content.image.includes=dc:title,dc:description,dc:creator,dc:subject,dc:rights,w:Comments,Exif IFD0:Image Description,Exif IFD0:Artist,Exif IFD0:Copyright,Exif IFD0:Windows XP .*,Exif SubIFD:User Comment,Object Name,Headline,Caption/Abstract,By-line,By-line Title,Credit,Source,Copyright Notice,Sub-location,City,Province/State,Country/Primary Location Name,Special Instructions,tEXt tEXtEntry,iTXt iTXtEntry,zTXt zTXtEntry

EXIF・XMP・IPTCの説明、作成者、キーワード、著作権、地名、Windowsのプロパティ、PNGのテキストチャンクなどを対象にします。新しいキーが古い設定ファイルに存在しなくても、実装側の初期値が使われます。

たとえば説明とタイトルだけに絞る場合は、対応版のfess_config.propertiesで次のように設定できます。これは初期値のリストを置き換えるため、ほかに必要な項目があれば追加します。

crawler.metadata.content.image.includes=dc:title,dc:description

設定を反映してクローラーを再起動し、対象画像を再取得するクロールで検索本文を比較します。空のリストは、画像のメタデータを本文に追加しません。これはOCRで抽出する文字自体を無効にする設定ではありません。画像以外のMIMEタイプには、この追加リストの制限は適用されません。

除外設定と抽出データを区別する

既存のcrawler.metadata.content.excludesは引き続き優先されます。初期値は次のとおりです。

crawler.metadata.content.excludes=resourceName,X-Parsed-By,Content-Encoding.*,Content-Type.*,X-TIKA.*,tk:.*,X-FESS.*

追加リストに一致しても、除外リストにも一致する項目は本文へ入りません。一方、サイズやカメラ設定などの通常の画像メタデータは抽出データに残るので、crawler.metadata.name.mappingやスクリプトで利用できます。本文への追加と、抽出そのものの削除は別の処理です。

IPTCとXMPに異なる作成者がある場合、TikaはIPTCのBy-lineをdc:creator、XMP側をxmp:dc:creatorにすることがあります。後者は初期の追加リストに含まれないため、必要なら実際の抽出名を確認して追加します。

一時ファイル由来の情報は抽出結果から取り除く

関連するfess-crawlerの修正では、Tikaが画像の一時保存先について返すFile Name、File Size、File Modified Dateを抽出結果へコピーしなくなります。tikaExtractor-123.outのような名前や一時保存時刻は元画像の情報ではないためです。この除去に新しい設定スイッチはありません。

これら3項目は、本文追加リストに戻すだけでは復活せず、マッピングやスクリプトでも取得できなくなります。元ファイルのサイズや更新日時を使う連携は、抽出器が一時ファイルから返す値に依存していないか確認してください。

既存の画像は本文を再作成する

更新前に登録した画像の本文は自動では変わりません。変更のない文書を差分クロールが省略する場合もあるため、実際に画像を再取得して本文抽出する条件でクロールします。説明やキーワードでヒットすることと、カメラ由来の数値が本文やハイライトに混ざらないことを比較すると効果を確認できます。

PRではEXIF・XMP・IPTC・Windowsプロパティ・PNGテキストを持つ画像などを使って確認しています。説明を持たずカメラ情報だけの画像は、OCRが無効なら本文が空になる場合があります。メタデータを検索用に補っていた運用では、対象画像の代表例で確認してください。

関連PR