tDiary with FESS （2023）

# はじめに
2019年、tDiary の検索システムを Hyper Estraier から FESS へ移行した。最初に試してから4年近く経過しているため、インストール手順を再度更新。FESSも、検索エンジンがOpenSearch対応したため、少し手順が変わっている。ハマりポイントも少しあったため、改めて。

https://qiita.com/Shakapon/items/e15c838310b5b019e20b


# FESSのインストール
FESS は APT/SNAPでは提供されない。zip/deb&rpm/docker のいずれかを利用する。公式サイトからダウンロードする必要がある。ここではdebを利用する。Ubuntuにサービス登録でき、サーバを自動起動させられるから。Docker 版も提供されているが、頻繁に落とし上げする環境なため、debを利用。

FESS 自体は検索エンジンを含まない。検索エンジンはOpenSearch/ElasticSearchを利用。もともとはElastic Searchだけだったが、14.0.1より ElasticSearch の OSS 実装である OpenSearchをサポートするようになった。最近はElastic Searchのサポートを切り出しているような記述も見受けられる。

## 手順
基本的には[FESSのドキュメント](https://fess.codelibs.org/ja/14.7/install/install.html)に従ってインストール。今回はFESS 14.7, OpenSearch 2.6.0, Java 17で検証した。
FESS は各バージョンごとに サポートする JavaとOpenSearch/ElasticSearch が明確に指定されている。バージョン固定で動作させることになる。切り替えを考えると、確かにdockerで動かした方がスマートかもしれない。
コンパチビリティは FESS のダウンロードサイトに記載あるので、これに従ってバージョンを確定させる。

https://fess.codelibs.org/ja/downloads.html

### OpenSearch/deb を利用する場合
APTも提供されているが、FESSは特定バージョンのOpenSearchを利用する必要がある。深いこと考えずパッケージをそのまま入手し、dpkg でインストール。

```console
$ sudo apt update
$ sudo apt -y install openjdk-17-jdk curl
$ wget https://artifacts.opensearch.org/releases/bundle/opensearch/2.6.0/opensearch-2.6.0-linux-x64.deb
$ sudo dpkg -i opensearch-2.6.0-linux-x64.deb
```

### OpenSearch-Fess連携設定
/etc/opensearch/opensearch.yml に下記を追加. 構築時点では/var/lib/opensearch/data/config/ は実態が存在せず、実際にFESSが動き出すと作成される。

```console
$ sudo vi /etc/opensearch/opensearch.yml
configsync.config_path: /var/lib/opensearch/data/config/
plugins.security.disabled: true
```

### 仮想メモリ設定
OpenSearchを動作させる際、Ubuntuのデフォルトの vm.max_map_count を変更する必要がある。これを設定変更しないとOpenSearchが起動してくれなかった。

https://zenn.dev/niaeashes/articles/f65f33e390eb41

`/etc/sysctl.conf` の最後の行に`vm.max_map_count = 262144`を追加して対処。この問題、FESS/OpenSearchをDockerで動かした場合でも発生した。ただこの問題。新しめのElastic Searchだと解消されている模様。

### FESS のインストール
Fessにはリポジトリがない様子。公式サイトからダウンロードしてインストールする。

```console
$ wget https://github.com/codelibs/fess/releases/download/fess-14.7.0/fess-14.7.0.deb
$ sudo dpkg -i fess-14.7.0.deb 

$ sudo /usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-analysis-fess:2.6.0
$ sudo /usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-analysis-extension:2.6.0
$ sudo /usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-minhash:2.6.0
$ sudo /usr/share/opensearch/bin/opensearch-plugin install org.codelibs.opensearch:opensearch-configsync:2.6.0
```

sha512 not foundという警告が出る。代わりにsha-1で処理するとのこと。
すべてのコマンドでContinue with installation? [y/N]と継続するかを確認されるので注意。yを強制するオプションもありそうだけれど、調査対象外。

### FESS の自動起動
パッケージでインストールすると、/usr/lib/systemd/system/fess.serviceが入る。

```console
$ systemctl list-unit-files |grep fess
fess.service                               disabled       
$ systemctl list-unit-files |grep opensearch
opensearch.service                         disabled   
$ sudo /bin/systemctl start opensearch.service
$ sudo /bin/systemctl start fess.service
$ systemctl list-unit-files |grep fess
fess.service                               enabled       
$ systemctl list-unit-files |grep opensearch
opensearch.service                         enabled   
$ sudo /bin/systemctl status opensearch.service # 起動確認
$ sudo /bin/systemctl status fess.service# 起動確認
```


止めるのなら下記で。

```console
$ sudo systemctl stop opensearch.service
$ sudo systemctl stop fess.service
```

### 動作確認
ブラウザでhttp://localhost:8080/ にアクセスし、FESSの画面が表示されれば成功。
動かない場合、http://localhost:9200/ へアクセス。こちらはOpenSearch/ElasticSearchの連携用インターフェース。こちらが動作していないと、FESSも正しく動かない（Port 8080へのアクセスが404/Not Foundとなる）

![Screenshot from 2019-07-25 05-47-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409463/b45dc4e8-5d94-ad2c-9d0f-a00b20987205.png)

# tDiaryとの連携
## tDiaryのクロール
ここからが本題。だが、前の版と同じロジックでできる。FESSからtDiaryをクロールさせる。
といっても、基本的には[FESSのチュートリアル](https://fess.codelibs.org/ja/articles/article-1.html#id11)に従って作成できる。

ひっかかったポイントで、**最大アクセス数 → FESSの1クローラで拾ってくるページ数**という点があった。検索対象は日記なので1日1ページできる。私の場合は検証時点で大体6,000ページあった。チュートリアルだと30とかになっていたので、拾ってこれるページ数がすごく少なくてちょっと悩んだ。同時スレッド数と誤読していた。10,000とした。数万とかにすると検索負荷が相当に重くなるらしい。

## クロールに関する今後の調査課題
全体を毎日、というよりも、新しいものだけを差分クロールするようにチューニングしたい。この辺りは運用してみて、調整が必要なら検討かな。ファイルシステム側にアクセスし、それをURI化することができればよいのだけれど、そこまでは調べてない。

## tDiary側からの検索
[FSS](https://fess.codelibs.org/ja/articles/article-4.html#fess-site-search-fss)を使用する。 Fess Site Searchの略だそうな。

1. FSS JS GeneratorでJSファイルを作成する
    2. [ここに記載されているスクリプト](https://fss-generator.codelibs.org/ja/docs/manual)を埋め込んだ検索結果ページ（result.htmlとか）を作成する。tDiaryのsqueeze.rbプラグインで出力されたHTMLファイルをベースに作成した。
3. tDiaryのヘッダに下記を埋め込む（FSSのスクリプトを少しカスタマイズ）

```html
<script>
  (function() {
    var fess = document.createElement('script');
    fess.type = 'text/javascript';
    fess.async = true;
    // FSS JSのURLをsrcに設定します
    fess.src = 'http://XXXXXX/tdiary/fess-ss.min.js';← 環境に応じて修正
    fess.charset = 'utf-8';
    fess.setAttribute('id', 'fess-ss');
    // Fessの検索APIのURLをfess-urlに設定します
    fess.setAttribute('fess-url', 'http://XXXXXX:8080/json'); ← 環境に応じて修正
    fess.setAttribute('fess-search-page-path', 'http://XXXXXX/tdiary/result.html');← 環境に応じて修正
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(fess, s);
    })();
</script>
<fess:search-form-only></fess:search-form-only>
```
'fess-search-page-path'を指定しないと、フォームの中だけで検索結果が出てきてしまう。検索結果は専用ページで出したいので、このAttributeを利用した。result.htmlはtDiaryで生成された日記のページをベースとして、FSS-Generatorのページで紹介されていたスクリプトを埋め込んで生成した。