Fessでは、画像とテキストを横断して検索できるマルチモーダル検索を利用できます。ただ、通常のテキストリスト形式の検索結果画面では、画像とドキュメントが混在した結果が直感的にわかりにくいという課題がありました。そこで、Fess 15.7で強化されたStaticテーマ(テーマ)の仕組みを使い、検索結果をサムネイルのギャラリーとして表示するmosaicテーマを用意しました。これにより、マルチモーダル検索の結果を一目で把握できるようになります。
この記事では、docker-multimodalsearchのDocker環境を例に、mosaicテーマを使ってマルチモーダル検索をわかりやすく見せる方法を紹介します。
マルチモーダル検索とは
マルチモーダル検索は、テキストのキーワード一致だけでなく、意味的な近さ(画像とテキストの関連度)でも検索できる仕組みです。docker-multimodalsearchでは、以下の2つの検索を組み合わせています。
- キーワード検索(BM25): 従来の全文検索。ページやPDF、Officeドキュメントの本文にマッチします。
- ベクトル検索(CLIP): CLIPモデルで生成した埋め込みベクトルによるkNN検索。テキストのクエリから、意味的に近い画像を見つけられます。
たとえば「山の夕日」や「mountain sunset」といったテキストで検索すると、キーワードにマッチしたドキュメントに加えて、CLIPが「山の夕日らしい」と判断した画像も同時にヒットします。日本語・英語のどちらのクエリでも画像検索できるのが特徴です。
Fessはこの2つの検索をdefault(BM25)とmulti_modal(CLIP)というサーチャーとして扱い、ハイブリッドなランク融合で1つの検索結果にまとめます。
Staticテーマ(mosaicテーマ)とは
マルチモーダル検索の結果は、画像とドキュメントが混在します。これを通常のテキストリストで表示すると、どれが画像でどれがドキュメントなのか、なぜヒットしたのかがわかりにくくなります。
そこで用意したのがmosaicテーマです。Fessのテーマ(Static Theme)機構を利用したギャラリーUIで、次のような見た目にしています。
- サムネイルを敷き詰めたメーソンリー(masonry)グリッドで表示
- 画像をクリックするとライトボックスで拡大表示
- 各結果に Keyword / Visual / Blend のバッジを表示し、キーワード(BM25)・ベクトル(CLIP)・その両方のどれでマッチしたかを可視化
バッジによって「この画像はベクトル検索でヒットした」「このドキュメントはキーワードと画像の両方でマッチした」といったことが一目でわかります。
mosaicテーマの本体はcodelibs/fess-themesリポジトリで管理されており、後述のセットアップスクリプトが同期して配置します。
環境構築
docker-multimodalsearchは.env駆動で、Docker Composeだけでマルチモーダル検索環境を起動できます。手順は次の通りです。
1. 取得と設定
git clone https://github.com/codelibs/docker-multimodalsearch.git
cd docker-multimodalsearch
cp .env.example .env
.envにはテーマやモデルの設定がまとまっています。テーマ関連は次の項目です。
# Theme
THEME_NAME=mosaic
FESS_THEMES_REPO=https://github.com/codelibs/fess-themes.git
FESS_THEMES_REF=main
# FESS_THEMES_DIR=/absolute/path/to/local/fess-themes # dev: use a local checkout instead of cloning
THEME_NAMEで使用するテーマ名を指定します。デフォルトはmosaicです。
2. セットアップスクリプトの実行
bash bin/setup.sh
このスクリプトはホスト側の準備を行うもので、bind-mount用ディレクトリの作成、system.propertiesの初期化、そしてfess-themesリポジトリからのmosaicテーマの同期を行います。同期先は./data/fess/usr/share/fess/app/themes/mosaicで、これがそのままFessコンテナにマウントされます。
テーマはsystem.propertiesのtheme.defaultで有効化されます。テンプレートには以下が設定されています。
theme.default=mosaic
thumbnail.enabled=true
suggest.search.log.enabled=true
suggest.document.enabled=true
login.required=false
3. スタックの起動
docker compose up -d
docker compose ps
初回起動時はCLIPの埋め込みサーバー用イメージのビルドと、CLIPモデル(約1.6GB)のダウンロードが行われるため、数分かかります。
4. サンプルコンテンツの投入とクロール
サンプル画像やドキュメントを配置してクロールします。
bash bin/fetch-sample-images.sh
その後、http://localhost:8080/admin/(初期ユーザーはadmin / admin)にログインし、クローラーでhttp://content/をクロールすると、検索対象のインデックスが作成されます。
5. 検索する
http://localhost:8080/を開いて検索してみましょう。多言語モデルを使っているため、日本語・英語のどちらでも試せます。
- 英語:
mountain sunset - 日本語:
山の夕日
mosaicテーマにより、CLIPがマッチした画像とキーワードでマッチしたページやPDFが、サムネイルのギャラリーとして一緒に表示されます。
サムネイル表示には-nobleイメージが必須
ギャラリー表示はサムネイルが主役です。ここで注意したいのが、使用するFessイメージです。デフォルトのAlpineベースのghcr.io/codelibs/fess:15.7.0イメージには、ImageMagick・poppler・LibreOfficeが含まれていません。これらが無いと、画像・PDF・Officeドキュメントのサムネイルが生成されず、ギャラリーが空のタイルだらけになってしまいます。
そのため、docker-multimodalsearchではこれら3つを同梱したUbuntu Nobleベースの-nobleバリアントを使用しています。
FESS_IMAGE=ghcr.io/codelibs/fess:15.7.0-noble
サムネイルのサイズはFESS_JAVA_OPTSで指定しています。
-Dthumbnail.width=512
-Dthumbnail.height=512
テーマ更新時の注意点
Fessはテーマのファイルをメモリにキャッシュします(StaticThemeResponder)。そのため、mosaicテーマのファイルを更新した場合は、Fessコンテナを再起動しないと変更が反映されません。
docker compose restart fess01
なお、.envでFESS_THEMES_DIRにローカルのfess-themesチェックアウトを指定すると、リポジトリをcloneせずローカルのテーマを使えます。テーマ自体を改修しながら見た目を調整したい場合に便利です。
まとめ
Fess 15.7のStaticテーマ機構を使ったmosaicテーマを利用することで、画像とドキュメントが混在するマルチモーダル検索の結果を、サムネイルのギャラリーとして直感的に表示できるようになりました。Keyword / Visual / Blendのバッジで「なぜヒットしたのか」も可視化されるため、マルチモーダル検索の挙動を理解しやすくなっています。
docker-multimodalsearchはDocker Composeだけで一式を起動できるので、マルチモーダル検索を試してみたい方はぜひ活用してみてください。