Fessの検索結果をCSV・JSONでエクスポートする

Fessの検索結果をCSVまたはJSONファイルとしてダウンロードできる機能を追加しました。検索で絞り込んだ文書の一覧を表計算ソフトに取り込んだり、別のツールで加工したりする用途に使えます。管理画面の検索ログ出力とは別の、検索利用者向けの機能です。

エクスポートを有効にする

デフォルトでは無効です。fess_config.propertiesで有効にし、必要に応じて件数や出力項目を調整します。

api.search.export=true
api.search.export.max.size=1000
api.search.export.fields=title,url_link,last_modified,content_length,filetype
api.search.export.rate.limit.per.minute=10

標準のbootstrapテーマでは、機能を有効にすると検索結果の状態表示の横にCSV・JSONのエクスポートメニューが表示されます。現在の検索条件を引き継ぎ、画面のページング条件は引き継ぎません。

APIからダウンロードする

エンドポイントはGET /api/v2/documents/exportです。formatはcsvまたはjsonで、省略するとCSVになります。通常の検索APIと同様に、q、ex_q、fields.*、sortなどを指定できます。

curl --get 'http://localhost:8080/api/v2/documents/export' \
  --data-urlencode 'q=運用手順' \
  --data-urlencode 'format=csv' \
  --output search-results.csv

これはログイン不要の環境での例です。ログイン必須の環境では、検索APIと同様にセッションやアクセストークンなど、環境に合った認証が必要になります。

エクスポートは内部で検索結果を順に取得します。numは無視され、ファイルに書き出す件数はapi.search.export.max.sizeで制限します。標準の上限は1000件です。

出力形式と閲覧権限

CSVはcsv.file.encodingの文字コードを使い、UTF-8ではBOMを付けます。複数値のフィールドは空白で連結し、数式として評価される文字で始まる値には引用符を付けて保護します。

JSONは{"data":[...]}形式で、複数値は配列のまま出力します。出力フィールドを追加しても、APIレスポンスで許可されていないフィールドは書き出しません。

文書の閲覧権限は通常の検索と同じロールフィルターで確認します。エクスポートを有効にしても、検索で閲覧できない文書まで取得できるようにはなりません。

運用上の制限

標準ではユーザーごとに1分あたり10回まで、ゲストはクライアントIPごとに制限します。超過時はHTTP 429とRetry-Afterを返します。

出力件数が多い場合は上限を確認してください。また、ダウンロード開始後に取得処理が失敗するとファイルが途中で終了する可能性があります。取得した件数を確認してから集計に利用すると安心です。エクスポート自体は検索ログには記録しません。

関連PR

Fessで画像とスキャンPDFをOCR検索する

Fessで、画像やスキャンしたPDFに含まれる文字を検索できるように、Tesseract OCRを有効にする設定を追加しました。紙の見積書や請求書をPDF化して保管している場合など、これまで本文を抽出できなかった資料を検索対象にできます。今回はFess 15.9向けにマージされた変更を紹介します。

OCRの仕組み

画像はTika経由でTesseractを呼び出して文字を抽出します。PDFは従来どおりPDFBoxで本文を取り出し、本文が空の場合に限ってTikaへ処理を引き継ぎ、ページを画像化してOCRを行います。文字情報のあるPDFを一律にOCRし直す仕組みではありません。

OCRはデフォルトでは無効です。Fessの設定に加え、クローラープロセスが動く環境にTesseract本体と利用する言語データが必要になります。

設定方法

日本語と英語を読み取る場合は、fess_config.propertiesに以下を設定します。

crawler.document.ocr.enabled=true
crawler.document.ocr.language=jpn+eng
crawler.document.ocr.timeout=120

言語のデフォルトはeng、タイムアウトのデフォルトは120秒です。タイムアウトは画像1枚、またはPDFの1ページに対するTesseractの実行時間です。変更後はFessを再起動します。既にインデックスされたファイルにOCR本文を反映するには、本文抽出が再実行されるように再クロールしてください。

Tesseractの言語データは次のコマンドで確認できます。

tesseract --list-langs

日本語の文字間に不要な空白が入り、単語検索に一致しなくなる問題を避けるため、OCR設定ではpreserve_interword_spacesも有効にしています。

Dockerで利用する場合

docker-fessにcompose/tesseract/Dockerfileを追加しました。Tesseract本体とosd、eng、jpnのデータを含めたイメージをビルドするための構成です。osdはページの向きなどを判定する処理で利用します。

Composeではimage:の代わりにbuild: ./tesseractを使い、既存のJVMオプションに以下を加えます。

-Dfess.config.crawler.document.ocr.enabled=true
-Dfess.config.crawler.document.ocr.language=jpn+eng

追加時点のDockerfileは15.8.0をベースにしているため、そのままでは今回の設定を利用できません。OCR対応の15.9ビルドにベースイメージを合わせる必要があります。

既存環境での注意点

独自に変更したtika.xmlが保持されている環境では、TesseractOCRParserの除外設定が残っていないか確認してください。OCRを有効にしてもTesseractが使えない場合は警告を出します。また、クロール設定のconfig.tika.tesseract.configは全体設定より優先されます。

本文が空だった際の再解析ではOCRをスキップするため、文字のない画像などに同じOCR処理を繰り返さないようにしています。対象資料と必要な言語を確認しながら有効にすると、画像として保存していた文書にも検索を広げられます。

関連PR

Fess 15.7のStaticテーマでソースコード検索を分かりやすく表示する

Fessでソースコード検索を手軽に試せるdocker-codesearchを、Fess 15.7に合わせて大きく刷新しました。Fess 15.7とOpenSearch 3.7を組み合わせ、Gitリポジトリをクロールしてソースコードを全文検索できる環境を、docker compose upだけで立ち上げられるようにしています。

今回のポイントは、Fess 15.7で追加された静的テーマ(Static Theme)の仕組みを活用し、ソースコード検索の見た目を分かりやすくしたことです。デフォルトで採用している「Code Search」テーマでは、各検索結果を1ファイルごとのコードカードとして表示し、言語バッジや行番号付きのコードスニペットを備えたGitHubのコード検索に近い画面になっています。これにより、どのリポジトリのどのファイルがヒットしたのかが一目で分かるようになりました。

ソースコード検索とdocker-codesearch

FessはOpenSearchをバックエンドに持つオープンソースの全文検索サーバーです。docker-codesearchは、そのFessをソースコード検索サーバーとして仕立てるためのDocker Compose環境で、自前でホストできるコード検索基盤として使えます。

ソースコードの取り込みにはfess-ds-gitデータストアプラグインを利用します。指定したGitリポジトリをクローンしてファイルを順にインデックスし、リポジトリ名・組織名・パスといったメタデータや、拡張子から判定した言語(filetype)を各ドキュメントに付与します。あわせて各行に行番号を付けてインデックスするため、検索画面側で行番号付きのコードスニペットを表示できるようになっています。

必要な環境

  • Docker および Git
  • Linuxの場合はOpenSearch向けにvm.max_map_countを262144以上に設定(Docker Desktopでは自動設定)

利用する主なコンポーネントは以下のとおりです。

  • Fess 15.7.0
  • OpenSearch 3.7.0(fess-opensearch)
  • fess-ds-git 15.7.0

イメージのバージョンは.envで一元管理しており、アップグレード時はここのFESS_VERSIONとOPENSEARCH_VERSIONを書き換えます。

FESS_VERSION=15.7.0
OPENSEARCH_VERSION=3.7.0

セットアップと起動

リポジトリをクローンし、セットアップスクリプトを実行してから起動します。

git clone https://github.com/codelibs/docker-codesearch.git
cd docker-codesearch
bash ./bin/setup.sh
docker compose up -d

bin/setup.shは、データディレクトリの作成、fess-ds-gitプラグインの取得、静的テーマの同期、そしてsystem.propertiesとfess_config.propertiesの生成を行います。初回起動時はインデックスの初期化に少し時間がかかります。準備が整えば、検索画面はhttp://localhost:8080/、管理画面はhttp://localhost:8080/admin(初期アカウントはadmin / admin)でアクセスできます。

Staticテーマでソースコード検索を分かりやすくする

今回の刷新で一番大きいのが、検索画面の作り方を変えたことです。以前は独自のJSPテーマ(fess-theme-codesearchプラグイン)で検索画面を組み、バーチャルホストに紐付けてテーマを切り替えていました。今回はFess 15.7で追加された静的テーマ(HTML/CSS/JavaScriptだけで検索画面を構成できる仕組み)に切り替えています。テーマはfess-themesリポジトリからbin/setup.shが同期します。

テーマの有効化は、system.propertiesの1行だけで行えます。以前のようにバーチャルホストの設定を書く必要はありません。

theme.default=codesearch

デフォルトで採用している「Code Search」テーマは、ソースコード検索に特化した作りになっています。

  • 1ファイルごとのコードカード: 検索結果を「組織 / リポジトリ ・ パス」のパンくずと、言語バッジ、行番号付きのコードスニペットとして表示します。マッチした語句はハイライトされ、リポジトリ上の該当箇所を開くリンクも付いています。
  • クエリ内の絞り込み修飾子: 検索ボックスにrepo:(リポジトリ)、org:(組織)、path:(パス)、file:(ファイル名)、lang:(言語)といった修飾子を書くと、そのままフィールド検索になります。たとえばrepo:fess lang:javaのように指定できます。
  • ファセットによる絞り込み: リポジトリ・言語・組織・パスといったファセットが左側に並び、件数を見ながら多段で絞り込めます。選んだ条件はクエリ文字列に反映されるため、検索結果のURLをそのまま共有できます。
  • ダークテーマ主体のIDE風デザイン: コードやパスを等幅フォントで表示するIDEに近い見た目で、ライトテーマへの切り替えにも対応しています。

以前のBootstrapベースの汎用的な検索画面と比べて、コード検索に必要な情報(言語・リポジトリ・行番号・該当箇所へのリンク)が最初から画面に並ぶため、検索結果がぐっと読み取りやすくなりました。

リポジトリの登録とクロール

検索対象のリポジトリは、Fessの公式CLIであるfessctlを使って登録します。docker-codesearchには、GitHubリポジトリを登録するためのbin/register_github.shラッパーも用意しています。デフォルトブランチの自動判定に対応し、冪等に登録できます。

export FESS_ENDPOINT=http://localhost:8080
export FESS_ACCESS_TOKEN=<管理画面のアクセストークン>

# 例: codelibs/fess-suggest を登録
./bin/register_github.sh codelibs fess-suggest

アクセストークンは管理画面の/admin/accesstoken/で発行できます。登録後にクローラーを実行すれば、リポジトリのソースコードがインデックスされ、検索できるようになります。

まとめ

docker-codesearchをFess 15.7 + OpenSearch 3.7に対応させ、docker compose upだけでソースコード検索を試せるようにしました。さらに、Fess 15.7のStaticテーマ「Code Search」を採用することで、1ファイルごとのコードカードや言語バッジ、行番号付きスニペット、repo:やlang:といった修飾子が使えるようになり、ソースコード検索の結果が格段に分かりやすくなっています。

詳細やソースコードはdocker-codesearchを参照してください。