tDiary with FESS


# はじめに
[tDiary](http://www.tdiary.org)を使って日記を書いていると、過去の日記を検索したくなる。Internetに載せている日記であればGoogleがクロールし、それを使って検索すればよい。でも、完全ローカルだとそうはいかない。もともとは[Hyper Estraier](https://fallabs.com/hyperestraier/index.ja.html) を使って実現していた。でもこれは開発が終了して久しく、Ubuntu 18.04ではとうとう収録パッケージから外れてしまった。次の検索システムが必要。できるだけ手軽に使えるよう、検索用 Interfaceが整備されたもので。というわけで、[FESS](https://fess.codelibs.org/ja/)

## 更新版の記事
2023年に再検証結果。検索エンジンがElasticSearch からOpenSearchに変わったこと、aptを利用せず、パッケージをそのままインストールする形で文書を更新。本資料は Obsolete なため、2023年版を参照のこと。

https://qiita.com/Shakapon/items/0ea6bd57c9ecec7a1431


## 本当は
[Groonga](http://groonga.org/)を試したかったのだけれど、Web検索のラッパーがすぐに見つけられなかったので断念。残念。Rubyとのラッパーもあるので、作りこみをするのならそっちのほうが向いているのかもしれない。

## そもそものtDiary環境
[tDiary on Ubuntu](https://qiita.com/Shakapon/items/bb81e3ca17f35101ac64)で構築した環境の続きで構築。

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

FESS 自体は検索エンジンを含まない。検索エンジンはOpenSearch/ElasticSearchを利用。もともとはElastic Searchだったが、14.0.1より OpenSearchをサポートするようになった。

## 手順
基本的には[FESSのドキュメント](https://fess.codelibs.org/ja/13.2/install/install.html)に従ってインストール。
FESS はJavaとOpenSearch/ElasticSearchのバージョンに強く依存。特定のバージョンでしか動作してくれない。バージョン固定で動作させることになる。切り替えを考えると、確かにdockerで動かした方がスマートかもしれない。

### Elastic Search を利用する場合

```console
$ sudo apt update
$ sudo apt -y install openjdk-17-jdk curl
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-amd64.deb
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-amd64.deb.sha512
$ shasum -a 512 -c elasticsearch-8.6.2-amd64.deb.sha512 
$sudo dpkg -i elasticsearch-8.6.2-amd64.deb
```

### ElasticSearch-Fess連携設定
/etc/elasticsearch/elasticsearch.yml に下記を追加

```console
$ sudo vi /etc/elasticsearch/elasticsearch.yml 
configsync.config_path: /var/lib/elasticsearch/config
```

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

```console
$ sudo dpkg -i fess-13.2.0.deb 

$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-fess:7.2.0
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-extension:7.2.0
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-configsync:7.2.0
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-dataformat:7.2.0
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-minhash:7.2.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 elastic
elasticsearch.service                      disabled   
$ sudo systemctl restart elasticsearch.service
$ sudo systemctl restart fess.service
$ sudo systemctl enable  elasticsearch.service
$ sudo systemctl enable  fess.service
 
$ systemctl list-unit-files |grep fess
fess.service                               enaabled       
$ systemctl list-unit-files |grep elastic
elasticsearch.service                      neabled   
```


止めるのなら下記で。

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

### 動作確認
ブラウザでhttp://localhost:8080/ にアクセスし、FESSの画面が表示されれば成功。
![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のページで紹介されていたスクリプトを埋め込んで生成した。