mirror of
https://example.com
synced 2024-11-25 07:06:38 +09:00
feat: use PGroonga for full-text search
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
This commit is contained in:
parent
182882f61d
commit
624f31ffaf
12 changed files with 149 additions and 44 deletions
89
README.md
89
README.md
|
@ -14,6 +14,9 @@
|
||||||
|
|
||||||
## 主要な変更点
|
## 主要な変更点
|
||||||
|
|
||||||
|
- 全文検索のエンジンを [PGroonga](https://pgroonga.github.io/) に変更
|
||||||
|
- PGroonga のインストールが必要になります!詳しくは[この投稿](https://post.naskya.net/notes/9ldi29amfanomef5)をご覧ください
|
||||||
|
- Meilisearch, Elasticsearch, Sonic は非推奨となります
|
||||||
- 「秘密」という公開範囲を追加
|
- 「秘密」という公開範囲を追加
|
||||||
- 宛先無しのダイレクト投稿を言い換えているだけです
|
- 宛先無しのダイレクト投稿を言い換えているだけです
|
||||||
- 既存の投稿を削除せずに後から秘密にすることもできます
|
- 既存の投稿を削除せずに後から秘密にすることもできます
|
||||||
|
@ -139,15 +142,14 @@
|
||||||
|
|
||||||
## インストール
|
## インストール
|
||||||
|
|
||||||
[Firefish のインストールスクリプト](https://git.joinfirefish.org/firefish/ubuntu-bash-install)のプロンプトで尋ねられるリポジトリの URL にこのリポジトリの URL を使ってください。
|
ToDo (#82)
|
||||||
|
|
||||||
```
|
遠回りな方法ですが、公式のインストールスクリプトを使いたい場合にはそれを用いて本家の Firefish をインストールしてから下記の手順でこのフォークに移行できます。
|
||||||
Repository url where you want to install:
|
|
||||||
> https://code.naskya.net/naskya/firefish
|
|
||||||
```
|
|
||||||
|
|
||||||
## アップデート
|
## アップデート
|
||||||
|
|
||||||
|
重要なお知らせがある場合にはアップデートスクリプトを通じてお伝えするので、必ず `update.sh` を用いてアップデートしてください。
|
||||||
|
|
||||||
1. サーバーのバックアップを取る
|
1. サーバーのバックアップを取る
|
||||||
1. サーバーを停止する
|
1. サーバーを停止する
|
||||||
```sh
|
```sh
|
||||||
|
@ -188,6 +190,64 @@ Repository url where you want to install:
|
||||||
$ cp -r calckey.old/custom calckey
|
$ cp -r calckey.old/custom calckey
|
||||||
$ cp -r calckey.old/.config calckey
|
$ cp -r calckey.old/.config calckey
|
||||||
```
|
```
|
||||||
|
1. 全文検索エンジン(Meilisearch, Sonic, Elasticsearch のいずれか)を使用している場合には、`.config/default.yml` からその設定を削除またはコメントアウトする
|
||||||
|
先頭に `#` をつけると設定をコメントアウトできます。
|
||||||
|
```yaml
|
||||||
|
#sonic:
|
||||||
|
# host: localhost
|
||||||
|
# port: 1491
|
||||||
|
# auth: SecretPassword
|
||||||
|
# collection: notes
|
||||||
|
# bucket: default
|
||||||
|
```
|
||||||
|
全文検索エンジンは停止またはアンインストールしてしまってよいです。本家の Firefish に戻るつもりがあるなら停止を、そうでなければアンインストールをおすすめします。
|
||||||
|
停止コマンドの例
|
||||||
|
```sh
|
||||||
|
$ sudo systemctl disable --now sonic
|
||||||
|
```
|
||||||
|
1. PostgreSQL のバージョンを確認する
|
||||||
|
```sh
|
||||||
|
$ psql --version
|
||||||
|
```
|
||||||
|
1. PGroonga をインストールする
|
||||||
|
インストールコマンドの例(詳しくは[この投稿](https://post.naskya.net/notes/9ldi29amfanomef5)を参考にしてください)
|
||||||
|
```sh
|
||||||
|
$ sudo apt install -y software-properties-common
|
||||||
|
$ sudo add-apt-repository -y universe
|
||||||
|
$ sudo add-apt-repository -y ppa:groonga/ppa
|
||||||
|
$ sudo apt install -y wget lsb-release
|
||||||
|
$ wget https://packages.groonga.org/ubuntu/groonga-apt-source-latest-$(lsb_release --codename --short).deb
|
||||||
|
$ sudo apt install -y -V ./groonga-apt-source-latest-$(lsb_release --codename --short).deb
|
||||||
|
$ echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release --codename --short)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
|
||||||
|
$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||||||
|
$ sudo apt update
|
||||||
|
$ sudo apt install -y -V postgresql-14-pgdg-pgroonga
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
for PostgreSQL 14.x
|
||||||
|
```
|
||||||
|
1. `.config/default.yml` に書かれているデータベースの名前を確認する(以下の例では `mk1`)
|
||||||
|
```yaml
|
||||||
|
db:
|
||||||
|
host: localhost
|
||||||
|
port: 5432
|
||||||
|
db: mk1 # <---
|
||||||
|
```
|
||||||
|
1. PostgreSQL のプロンプトを起動する(`mk1` の部分は自分のデータベース名に変えて実行)
|
||||||
|
```sh
|
||||||
|
$ sudo -iu postgres psql --dbname=mk1
|
||||||
|
```
|
||||||
|
以下のような表示が出てコマンドの入力待ちになります。
|
||||||
|
```
|
||||||
|
psql (16.0)
|
||||||
|
Type "help" for help.
|
||||||
|
|
||||||
|
mk1=#
|
||||||
|
```
|
||||||
|
1. 以下のコマンドを実行して PGroonga の拡張機能を有効にする
|
||||||
|
```
|
||||||
|
CREATE EXTENSION pgroonga;
|
||||||
|
```
|
||||||
|
1. `\q` というコマンドを実行するか Ctrl+D を押して PostgreSQL のプロンプトを終了する
|
||||||
1. 新しい Firefish のディレクトリに入ってビルドする
|
1. 新しい Firefish のディレクトリに入ってビルドする
|
||||||
```sh
|
```sh
|
||||||
$ cd calckey
|
$ cd calckey
|
||||||
|
@ -218,9 +278,24 @@ Repository url where you want to install:
|
||||||
```sh
|
```sh
|
||||||
$ ./update.sh
|
$ ./update.sh
|
||||||
```
|
```
|
||||||
1. このフォークで加えられたデータベースへの変更を取り消す(`dbname`(以下の例では `mk1`)には `.config/default.yml` に記載されている PostgreSQL のデータベース名(`db:` の後に書かれているもの)を指定する)
|
1. `.config/default.yml` に書かれているデータベースの名前を確認する(以下の例では `mk1`)
|
||||||
|
```yaml
|
||||||
|
db:
|
||||||
|
host: localhost
|
||||||
|
port: 5432
|
||||||
|
db: mk1 # <---
|
||||||
|
```
|
||||||
|
1. このフォークで加えられたデータベースへの変更を取り消す(`mk1` の部分は自分のデータベース名に変更する)
|
||||||
```sh
|
```sh
|
||||||
$ sudo -iu postgres psql --dbname=mk1 --file=neko/revert.sql
|
$ sudo -iu postgres psql --file=neko/revert.sql --dbname=mk1
|
||||||
|
```
|
||||||
|
1. PGroonga をアンインストールする
|
||||||
|
アンインストールするコマンドの例
|
||||||
|
```sh
|
||||||
|
$ sudo apt purge --remove postgresql-14-pgdg-pgroonga
|
||||||
|
$ sudo add-apt-repository --remove ppa:groonga/ppa
|
||||||
|
$ sudo apt-key del ACCC4CF8
|
||||||
|
$ sudo apt update
|
||||||
```
|
```
|
||||||
1. Firefish がインストールされているディレクトリの親ディレクトリ (e.g., `/home/calckey`) に行く
|
1. Firefish がインストールされているディレクトリの親ディレクトリ (e.g., `/home/calckey`) に行く
|
||||||
```sh
|
```sh
|
||||||
|
|
|
@ -2,15 +2,13 @@ version: "3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
image: registry.joinfirefish.org/firefish/firefish
|
image: firefish
|
||||||
|
build: .
|
||||||
container_name: firefish_web
|
container_name: firefish_web
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- redis
|
- redis
|
||||||
### Uncomment one of the following to use a search engine
|
|
||||||
# - meilisearch
|
|
||||||
# - sonic
|
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
networks:
|
networks:
|
||||||
|
@ -33,7 +31,7 @@ services:
|
||||||
|
|
||||||
db:
|
db:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
image: docker.io/postgres:12.2-alpine
|
image: docker.io/groonga/pgroonga:latest-alpine-12
|
||||||
container_name: firefish_db
|
container_name: firefish_db
|
||||||
networks:
|
networks:
|
||||||
- calcnet
|
- calcnet
|
||||||
|
@ -42,33 +40,6 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./db:/var/lib/postgresql/data
|
- ./db:/var/lib/postgresql/data
|
||||||
|
|
||||||
### Only one of the below should be used.
|
|
||||||
### Meilisearch is better overall, but resource-intensive. Sonic is a very light full text search engine.
|
|
||||||
|
|
||||||
# meilisearch:
|
|
||||||
# container_name: meilisearch
|
|
||||||
# image: getmeili/meilisearch:v1.1.1
|
|
||||||
# environment:
|
|
||||||
# - MEILI_ENV=${MEILI_ENV:-development}
|
|
||||||
# ports:
|
|
||||||
# - "7700:7700"
|
|
||||||
# networks:
|
|
||||||
# - calcnet
|
|
||||||
# volumes:
|
|
||||||
# - ./meili_data:/meili_data
|
|
||||||
# restart: unless-stopped
|
|
||||||
|
|
||||||
# sonic:
|
|
||||||
# restart: unless-stopped
|
|
||||||
# image: docker.io/valeriansaliou/sonic:v1.4.0
|
|
||||||
# logging:
|
|
||||||
# driver: none
|
|
||||||
# networks:
|
|
||||||
# - calcnet
|
|
||||||
# volumes:
|
|
||||||
# - ./sonic:/var/lib/sonic/store
|
|
||||||
# - ./sonic/config.cfg:/etc/sonic.cfg
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
calcnet:
|
calcnet:
|
||||||
# web:
|
# web:
|
||||||
|
|
4
neko/flags/.gitignore
vendored
Normal file
4
neko/flags/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
7
neko/messages/install_pgroonga
Normal file
7
neko/messages/install_pgroonga
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
| This Firefish fork now requires PGroonga (https://pgroonga.github.io/), |
|
||||||
|
| so PLEASE INSTALL PGroonga BEFORE UPGRADING!!! |
|
||||||
|
| |
|
||||||
|
| For the detailed explanation, see: |
|
||||||
|
| https://post.naskya.net/notes/9ldi29amfanomef5 |
|
||||||
|
-------------------------------------------------------------------------
|
|
@ -1,3 +1,9 @@
|
||||||
|
-- pgroonga
|
||||||
|
DROP INDEX "public"."IDX_f27f5d88941e57442be75ba9c8";
|
||||||
|
DROP INDEX "public"."IDX_065d4d8f3b5adb4a08841eae3c";
|
||||||
|
DROP INDEX "public"."IDX_fcb770976ff8240af5799e3ffc";
|
||||||
|
DROP EXTENSION pgroonga CASCADE;
|
||||||
|
|
||||||
-- emoji-moderator
|
-- emoji-moderator
|
||||||
ALTER TABLE "user" DROP COLUMN "emojiModPerm";
|
ALTER TABLE "user" DROP COLUMN "emojiModPerm";
|
||||||
DROP TYPE "public"."user_emojimodperm_enum";
|
DROP TYPE "public"."user_emojimodperm_enum";
|
||||||
|
|
27
packages/backend/migration-neko/1698420787202-pgroonga.js
Normal file
27
packages/backend/migration-neko/1698420787202-pgroonga.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
export class Pgroonga1698420787202 {
|
||||||
|
name = "Pgroonga1698420787202";
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_f27f5d88941e57442be75ba9c8" ON "note" USING "pgroonga" ("text")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_065d4d8f3b5adb4a08841eae3c" ON "user" USING "pgroonga" ("name" pgroonga_varchar_full_text_search_ops_v2)`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_fcb770976ff8240af5799e3ffc" ON "user_profile" USING "pgroonga" ("description" pgroonga_varchar_full_text_search_ops_v2) `,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP INDEX "public"."IDX_fcb770976ff8240af5799e3ffc"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP INDEX "public"."IDX_065d4d8f3b5adb4a08841eae3c"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP INDEX "public"."IDX_f27f5d88941e57442be75ba9c8"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ export class Note {
|
||||||
})
|
})
|
||||||
public threadId: string | null;
|
public threadId: string | null;
|
||||||
|
|
||||||
|
@Index() // USING pgroonga
|
||||||
@Column("text", {
|
@Column("text", {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -38,6 +38,7 @@ export class UserProfile {
|
||||||
})
|
})
|
||||||
public birthday: string | null;
|
public birthday: string | null;
|
||||||
|
|
||||||
|
@Index() // USING pgroonga pgroonga_varchar_full_text_search_ops_v2
|
||||||
@Column("varchar", {
|
@Column("varchar", {
|
||||||
length: 2048,
|
length: 2048,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -64,6 +64,7 @@ export class User {
|
||||||
})
|
})
|
||||||
public usernameLower: string;
|
public usernameLower: string;
|
||||||
|
|
||||||
|
@Index() // USING pgroonga pgroonga_varchar_full_text_search_ops_v2
|
||||||
@Column("varchar", {
|
@Column("varchar", {
|
||||||
length: 128,
|
length: 128,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -91,7 +91,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
query
|
query
|
||||||
.andWhere("note.text ILIKE :q", { q: `%${sqlLikeEscape(ps.query)}%` })
|
.andWhere("note.text &@~ :q", { q: `${sqlLikeEscape(ps.query)}` })
|
||||||
.andWhere("note.visibility = 'public'")
|
.andWhere("note.visibility = 'public'")
|
||||||
.innerJoinAndSelect("note.user", "user")
|
.innerJoinAndSelect("note.user", "user")
|
||||||
.leftJoinAndSelect("user.avatar", "avatar")
|
.leftJoinAndSelect("user.avatar", "avatar")
|
||||||
|
|
|
@ -78,8 +78,8 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
const nameQuery = Users.createQueryBuilder("user")
|
const nameQuery = Users.createQueryBuilder("user")
|
||||||
.where(
|
.where(
|
||||||
new Brackets((qb) => {
|
new Brackets((qb) => {
|
||||||
qb.where("user.name ILIKE :query", {
|
qb.where("user.name &@~ :query", {
|
||||||
query: `%${sqlLikeEscape(ps.query)}%`,
|
query: `${sqlLikeEscape(ps.query)}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also search username if it qualifies as username
|
// Also search username if it qualifies as username
|
||||||
|
@ -115,8 +115,8 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
if (users.length < ps.limit) {
|
if (users.length < ps.limit) {
|
||||||
const profQuery = UserProfiles.createQueryBuilder("prof")
|
const profQuery = UserProfiles.createQueryBuilder("prof")
|
||||||
.select("prof.userId")
|
.select("prof.userId")
|
||||||
.where("prof.description ILIKE :query", {
|
.where("prof.description &@~ :query", {
|
||||||
query: `%${sqlLikeEscape(ps.query)}%`,
|
query: `${sqlLikeEscape(ps.query)}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ps.origin === "local") {
|
if (ps.origin === "local") {
|
||||||
|
|
12
update.sh
12
update.sh
|
@ -62,6 +62,18 @@ else
|
||||||
say "This script seems to be up-to-date!\n"
|
say "This script seems to be up-to-date!\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
## show messages
|
||||||
|
for message in neko/messages/*; do
|
||||||
|
file=$(basename -- "${message}")
|
||||||
|
if [[ ! -f "neko/flags/${file}" ]]; then
|
||||||
|
say "There is an important notice!"
|
||||||
|
cat "${message}"
|
||||||
|
touch "neko/flags/${file}"
|
||||||
|
say "To read this again, run: \$ cat ${message}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
## write version info
|
## write version info
|
||||||
say "Writing version info to package.json..."
|
say "Writing version info to package.json..."
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue