[令和最新] Fess + opensearchで全文検索環境を構築

このblogで過去に何度かFessの運用メモを書いてきました。が、内容が古くなってしまったり、もう不要となったパッチ、より効率的な運用に変えてしまっている箇所もあり気になっていました。

今回、Fessのバージョンを上げた際にElasticsearchからOpenSearchへバックエンドを変更したのが良い機会と思い、Fessを使った全文検索システムの運用メモを整理し直しました。

はじめに

自炊したPDFファイルを自宅サーバに配置し、それらのPDFファイルを全文検索するシステムを Fess を使い構築しています。安定稼働し始め現状に不満がないと新しいバージョンがリリースされてもなかなかアップデートをする気分にならず、気づくと2年以上バージョンアップをサボっていました(もちろんFessは安定稼働していて、全文検索は調べ物の時便利に利用していました)

先日、久々にFessのページを訪れると最新バージョンは14.13.0と自宅サーバで稼働しているのバージョンよりかなり上がっていました(自宅サーバでは、13.15.3 2021.12.16リリースでした)。

マニュアルを軽く読んでいくと、最新バージョンのバックエンドにElasticsearchの名前が書かれておらず、代わりにOpenSearchがサポートされますとあります。ElasticsearchをOpenSearchへ置き換えなくちゃいけないのか。いろいろ変更がありそうだし少し悩んだのですが、丁度暇だったのでアップデートする事にしました。

通常、バックエンドを変更する時は、データの移動などの作業が発生すると思います。しかし、Fessで利用するデータは自炊したPDFファイルの内容です。またクロールすれば良いので、今回、データの移動は行いません。

OpenSearchとFessをクリーンな状態からインストールし、安定運用できるように設定するところまでをゴールとします。

想定環境

OS Debian 12 bookworm (Stable)
HTTP Server apache2 2.4.59
Java runtime openjdk17
Fess 14.13.0
OpenSearch 2.13.0
  • 自宅サーバでは、Debian12 Stableが稼働中
    • 自宅内部ネットワークとインターネットに足を出していて、外部から接続可能
  • OpenSearchへはHTTPで接続
    • 内部利用なのでSSLは設定しない
    • loopback:9200にbindさせる
  • Fess
    •  loopback:8080にバインドさせる
    • apache2でリバースプロキシをする
    • ファイルシステムを直接参照してcrawlする
  • 検索対象ファイル
    • PDFとTXTファイルを対象とする
    • 対象のPDFファイルはOCR処理をして透過テキストが埋め込まれていること
    • 縦書きPDFファイルはファイル名の最後が _v_.pdf となっていること
      例) 縦書き_v_.pdf というようなファイル名にしている

OpenSearch

OpenSearchは全文検索をするソフトウェアで検索エンジンと呼ばれています。Elasticsearchから派生したプロダクトでAmazonによりメンテナンスされています。ライセンス周りでもめて、個人利用ならばElasticsearchを利用可能ですが、FessのマニュアルにOpenSearchと書かれているので、OpenSearchをインストール/設定します。

インストール

基本的に、公式サイトのインストールガイドの通りに進めていけば特に問題は無いはず。

Java runtime 11 or 17が必要です。導入されていなければインストールが必要です。

全てdebianパッケージでインストールを行うので、aptの各種設定をマニュアル通りに実施後にパッケージのインスートルを実施します。Debian packageは、install時に初期パスワードをコマンドラインで指定が必要です。

今回導入するFess-14.13.0に対応するOpenSearchのバージョンは、2.13.xです。正しいバージョンがインストールされたか確認しておきましょう。
※ バージョンが異なっていたら、要求されるバージョン番号を指定してインストールします。
例) env OPENSEARCH_INITIAL_ADMIN_PASSWORD=xxxx apt-get install opensearch=2.13.0

Fessで利用するPluginも導入してしまいます。導入するpluginとバージョンは、fessのバージョンによって異なるので、必ずマニュアルを参照すること。

設定

デフォルトの状態から修正する箇所はあまりありませんが

  • ヒープメモリの最大値を変更。環境によって違うと思いますので良さげな感じで。
  • loopbackにバインド
  • fessに必要なpluginの設定 (configsyncの行)
  • opensearchのセキュリティ設定を解除

起動と確認

まずは、サービスの起動

設定ファイルの書き方を間違えなければ localhost:9200 で Listenされているハズです。

curlコマンドでGETして確認します。このようにレスポンスが返ればOpenSearchのインストールは完了です。

Fess

いよいよFessのインストールに入ります。FessもDebianパッケージでインストールしますので、公式マニュアル通りに進めれば躓くことは無いと思います。

インストール

  • OpenSearchへプラグインのインストール
  • OpenSearchへプラグインの設定追加

上記作業は、OpenSearchのインストール時に作業済みです。

次にgithubのリリースページからパッケージをダウンロードします。現在は4.13.0が最新なのでそれをダウンロードしてからインストールします。

余談ですがFessとOpenSearchのバージョンには依存関係がありますので、導入しようとしているバージョンのFessが現在稼働中のOpenSearchのバージョンと適合しているかどうかを確認してください。githubのreleaseページで確認できます。

設定

localhost:8080 へバインドする
apacheで reverse proxyをしたいので、localhostへバインドさせます。

おま環かもしれませんが、PATHの指定がおかしくて修正しました。

check

fessを起動してエラーが出力されないことを確認します。エラーが出ていたら内容に従って設定を修正します。

最近のopensearchは各種ファイルのpermissionが厳しめに変わっていて、fessがファイルを適切に読み込めないエラーを吐くかもしれません。その場合は、fessユーザのgroupにopensearchをいれてあげましょう。

問題なく起動したらopensearchにfessがいくつかインデックスを作成します。インデックスの作成が確認できればfessインストールは完了です。

チューニング

ヒープメモリの最大量を大きく

最適値は環境によって異なると思います、fessがメモリ不足のログを吐いたら大きくしていけばよろしいかと。

最大検索ファイルサイズを大きく

初期設定状態のfessでは10Mバイトまでのファイルしかインデックスしません。用途次第ですが、自炊した本をPDF化すると、大部分は50Mバイト以上のファイルとなります。ぼくがスキャンした本で最も大きかったのが600Mバイト位。なので、余裕をもって1Gバイトまで検索対象とするように設定しました。

検索結果の表示数のデフォルトを変更

初期値では検索結果を10件づつ表示するようになっている。個人的に検索結果は100件くらい表示して欲しい。検索表示件数のデフォルト値を変更する。

trouble shoot

FessのTopページへアクセスすると 404 としか表示されない

Elasticsearch または OpenSearch 上にFessのインデックスが無い/足りない場合に発生しました。Fessのログを参考にしてなぜインデックスの作成に失敗したのかを調べ、原因を解消します。

ファイルシステムの直接クロールを試みるとファイルがあるのにみつからないと表示される

OSのlocaleが足りない事が原因かもしれません。うちのDebianでは、en_US.UTF-8 のみが有効になっていました。ja_JP.UTF-8 を追加(コメントを外す)してから、locale-gen を実行することで、fessが直接ファイルシステム上にあるUTF-8で書かれたファイルを参照できるようになりました。

ラベルの対象に日本語パスを指定すると認識されない

2つの方法があり、どれが正しいのがよくわからないのですが、うちの今の環境では、日本語文字列をURL ENCODEしてうまく動いています。

もうひとつの方法は、#DISABLE_URL_ENCODEという文字を直前に挿入することです。クロール対象がsambaでアクセスするファイルシステムの時は、この方法が上手くいっていました。

現在は、Debianが直接mountしているファイルシステム上にすべてのアーカイブが置いてあるので、今はこの方法は試していません。

サムネイルの生成に失敗する

古いバージョン2021年頃?のfessではサムネイルの生成がおかしかったのですが、現在のバージョンでは期待する動作をしています。

運用

縦書きPDFの検索

うちの環境依存なのかもしれませんが、縦書きPDFファイルの検索がうまくできません。利用しているOCRツールのせいなのか、そういう仕様なのか。PDFビュアーでも検索できたり、できなかったりします。

具体的には、縦書きPDFにOCR処理をした透過PDFに埋め込まれる文字の間にスペースが挿入されてしまうのです。opensearchに保存されている文字列を観察してみるとよくわかります。

Webを検索してみても情報が見つからず、苦肉の策、力業で運用できているのでご紹介します。きっと識者ならばもっと良い解決法をご存知なのでしょうね。

縦書きPDFファイルに命名規則を適用する

fessのラベル機能を利用したいので、正規表現で引っかけやすく、普通にファイル名を付ける場合と競合しないことが大切です。

うちでは、ファイルの最後に _v_ を付けることにしました。

こんな感じです

縦書きPDFファイルにFessでラベルを付ける

fessにはドキュメント分類の為にラベルを付ける機能が実装されています。想定されている使い方としては異なるかもしれませんが、ラベルの値はopensearch内に書き込まれますから縦書きPDFファイルを判別するために利用します。

先の縦書きファイルの命名規則を「対象とするパス」に正規表現で記述して縦書きファイルに verticalという値を付与します。

opensearch内にある縦書きPDFのテキストからスペースを削除する

いささか乱暴すぎる処理ですが、これくらいしか思いつかなかったので。opensearch内の文字列を直接読むわけではないので、これでよしとしました。

スペースの削除はpythonスクリプトで行っています。fessの定期クローラが動いた後に走るよう、適当な時刻にcronから起動しています。

idx_nameはfessのindexファイルで起動した日付で作成されます。個々の環境で異なりますので、正しいindex名に書き換えてください。

opensearch-pyopensearch-dsl モジュールを利用しています。pipなどで導入してください。

うちでは 04:00  に Fess のクローラが走ります。Fessのクローラがまっさらな状態からすべてのファイルを処理するのに90分くらいかかるので余裕をみて 06:00 にこのスペース削除スクリプトを実行させています。

apache2でのリバースプロキシ設定

Fessを直接外部へ晒さず、リクエストはapacheで受けます。既存のVirtualHostへProxy設定を追加するくらいなら、新しくVirtualHostを作成するほうが楽だしシンプルです。SSL対応も簡単です。

  1. DNSレコードを準備する
    1. 固定IPでない場合はDynamicDNSなどを検討
    2. SSL対応する場合は証明書も準備する
  2. apache2にvirtualhostを作成
    1. 受けたリクエストをlocalhostへ転送(Fessは、loopback:8080でListen)

apache2の設定の必須な箇所を抜粋

注意: Fessは、検索結果から直接ドキュメントを参照できるので、外部から認証なしで検索できるような設定をするときは、apache側で認証をかけましょう。もちろん、Fess側で「システム -> 全般 -> ログインが必要」にチェックを入れるのも有用でしょう。

うちのデータ運用方法

  1. 自炊したデータは、Windowsマシン に保存する(OCR処理などが済んだもの)
    1. Windows から Microsoft One Drive へ双方向を同期する
  2. WindowsマシンからFessが参照する File system へ一方通行コピーする
    1. Fessが参照するFile SystemをWindowsマシン上でネットワークドライブとしてドライブレターを割り当てておけば、Robocopy.exe を使い簡単に同期ができる。
  3. iPadで PDF Expert の One Drive を同期フォルダ指定し、オフライン状態でも Read / Write を可能にする
    1. ネットワークに接続したときに One Drive と双方向同期を行い、オフライン状態時の更新を同期する
    2. One Drive へ同期された変更は Windowsマシン上へ自動で同期されるので、(2)の操作を実施

ユースケース
通勤時にiPadでPDFを読み書きする

通勤電車内ではiPad上のPDF Expert で自炊ファイル読みながらメモを書き入れる。高速なWiFiが利用できる環境に来たらPDF Expert で One Driveへ更新されたファイルの同期を行う(帰宅後の自宅でも可)。帰宅後 Windowsマシンから Fess側のFile Systemへ同期を実施。

新しい本をスキャンした

OCR処理が完了したPDFファイルが出来上がったらWindowsマシンのOne Driveフォルダへコピーをする。データはOne Driveと同期される。高速なWiFiが使える環境下にあるiPadでPDF Expertを起動しOne Driveとフォルダを同期する。WindowsマシンでFessが参照するFile Systemへコピー(Robocopy.exe)

Windows上で自炊PDFファイルを読みながら書き込む

Windows上のOne Drive フォルダ内のPDFファイルを直接 PDF Exchange Editorで開く。付箋やブックマークなどの書き込みが発生したら、自動で One Driveへ同期される。更新した自炊PDFファイルをFessが参照するFile Systemへコピー(Robocopy.exeで全体を同期)最後にiPadのPDF ExpertでOne Driveからファイルを同期する。

蛇足

OneDriver → iPadへの同期は結構時間がかかります。最近のWiFiは速いとはいいつつも有線に勝るものなし。ぼくは同期の時だけ iPadを有線接続しています。WiFiよりも安定しているのがいいですね。

カテゴリー PC

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)