MisskeyにPGroongaを導入してAND/OR/NOT検索を行う&cwも検索に含める
Ubuntu22.04LTS / PostgresSQL15 / Misskey v13.14.2
※2023/09/26更新 Misskey内で完結するように割と修正
Misskey内の検索を強化したいもののMeilisearchの形態素分析がいまいちで検索したい語が探せない(「あんぱん」で「あんぱんまん」がヒット出来ない)ので、PostgresSQL拡張の日本語全文検索拡張PGroongaの導入メモです。
またnote.textだけでなくnote.cwの注意書き部分も検索範囲にします。
PGroongaを使って自鯖のMisskeyで快適にエゴサする tamainaさんの記事を参考にさせて頂いています。
PGroongaを追加したPostgresDBをコンテナを作成
PGroonga入りのPostgreSQLのDockerfileを作成してMisskeyのDocker composeに導入します。
PGroongaのDockerfileの作成
misskeyフォルダ内にpg.Dockerfileを作成します
pg.Dockerfile
FROM postgres:15-bookworm # Add Tini ENV TINI_VERSION v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini ENTRYPOINT ["/tini", "--"] # PGroonga install ENV PGROONGA_VERSION=3.1.1-1 RUN \ apt update && \ apt install -y -V wget && \ wget https://apache.jfrog.io/artifactory/arrow/debian/apache-arrow-apt-source-latest-bookworm.deb && \ apt install -y -V ./apache-arrow-apt-source-latest-bookworm.deb && \ rm apache-arrow-apt-source-latest-bookworm.deb && \ wget https://packages.groonga.org/debian/groonga-apt-source-latest-bookworm.deb && \ apt install -y -V ./groonga-apt-source-latest-bookworm.deb && \ rm groonga-apt-source-latest-bookworm.deb && \ apt update && \ apt install -y -V \ postgresql-15-pgdg-pgroonga=${PGROONGA_VERSION} \ groonga-normalizer-mysql \ groonga-token-filter-stem \ groonga-tokenizer-mecab && \ apt clean && \ rm -rf /var/lib/apt/lists/* CMD ["docker-entrypoint.sh", "postgres"]
適当なpgroongaフォルダにDockerfileという名前のファイルを作成し、PGroonga/Docker から適切なDockerfileを選んで内容をコピペで貼り付け、下記コマンド実行でコンテナイメージを作成します
Misskeyの設定
Misskeyのdocker-compose.ymlの更新
Misskeyのフォルダに移動し、docker-compose.ymlのPostgreSQLのイメージ欄を変更します
db: restart: always image: misskey-db:latest ←変更 build: ←追加 context: . ←追加 dockerfile: pg.Dockerfile ←追加 // 以下略
マイグレーションファイルの作成
データベースにインデックスを追加します。巻き戻しが効くようにTypeORMのマイグレーションファイルを作成して適用します。
note.textカラムとnote.cwカラムに適用します。複数のカラムにまたがったインデックスを使用します。精度を上げるなら各カラムのインデックスも作った方が良いかも(容量は食いますがおひとりさま用サーバーなので…)
念のためこの段階でDBのバックアップは取っておくこと。
sudo docker compose run --rm web pnpm dlx typeorm migration:generate -d ./packages/backend/ormconfig.js ./packages/backend/migration/AddPgroongaIndexes
…でマイグレーションファイルを作成しようとしたらDockerコンテナ内なのですぐ消えてしまうのでありました…。(それはそう)
代わりに/packages/backend/migration/1691850149834-AddPgroongaIndexes.jsファイルを手動で作成して以下を入力(タイムスタンプは↑で失敗したときのを流用)
export class AddPgroongaIndexes1691850149834 { name = 'AddPgroongaIndexes1691850149834' async up(queryRunner) { await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS pgroonga;`); await queryRunner.query(`CREATE INDEX idx_note_text_cw_pgroonga ON note USING pgroonga(text, cw);`); } async down(queryRunner) { await queryRunner.query(`DROP INDEX idx_note_text_cw_pgroonga;`); } }
下記を実行してDBのマイグレーションを行います。
sudo docker compose build sudo docker compose run --rm web pnpm migrate // 上手く行かなかったらこちらで // sudo docker compose run --rm web pnpm run init
Misskey本体の書き換え
ユーザー検索には適用せずノート検索だけに利用するのでNote絡みの部分のみ変更します。
packages/backend/src/models/entities/Note.ts
10行目付近、インデックスを追加させます
@Entity('note') @Index('idx_note_text_cw_pgroonga', ['text', 'cw'], { using: 'pgroonga' }) export class Note { // ~~ 以下略 ~~
packages/backend/src/core/SearchService.ts
185行目付近のelseブロック付近、ILIKE検索部を&@~演算子に書き換え、CWも検索範囲に
query .andWhere('(note.text &@~ :q OR note.cw &@~ :q)', { q: q })
PGroonga拡張の「&@~」演算子を使うことで「AB CB」や「A OR B」のような検索が行えるようになります。
あとは通常通りビルドすると完了です🎉
できたよ~~
AND検索
OR検索
NOT検索(除外検索)
CWの注釈もヒット
日本語全文高速検索になるとどの程度かわかりませんが、とりあえずおひとりさま用サーバーで簡易的にAND/OR/NOT検索が付けられるのは嬉しいです。YATTA~~🌸
とりあえずは目的完了です。
課題点
上記だとcwとtextに跨がったAND検索は出来ない(cwに「ひよこ」textに「にわとり」を「ひよこ にわとり」でヒットできない)ので、この辺はsearchNoteメソッドをもうちょっと弄りたいかもです。
追記
PostgreSQLのDockerfileを作ってMisskeyと一緒にビルドするようにしました。docker-compose.yml
の下記をimageから書き換えしておくこと。
db: restart: always build: context: . dockerfile: Dockerfile-pg networks: - internal_network