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