大概率之后会继续补充内容。

前言

特别感谢 debula、light、shykana 近期与之前的帮助!

Pleroma 官方文档 How to enable text search for Chinese, Japanese and Korean 中对过程进行了简要说明,并提供了多个拓展可供选择,这里以 pg_cjk_parse为例,因为我个人曾在安装这个拓展的实例尝试搜索,感觉效果不错(但它不支持单字符搜索),除支持简体中文外,该拓展还支持繁体中文、日文和韩文。

之前在 debula 指导下也曾试着安装 pg_jieba 拓展包,从结果上看搜索的确支持了中文,但不知是 jieba 本身的原因,还是我在安装期间不自觉操作出现了失误,搜索结果并不理想,数量少且结果都是很久之前的,且分词不支持繁中。拖了很久后,终于这次又在 debula 指导下重新尝试启用 pg_cjk_parser 拓展。

Pleroma 可以搜索到 public 与 unlisted 两种状态的 status,无法搜索到 followers-only 状态的 status(不像 Mastodon 能够搜索到互动过的 followers-only 嘟文),不过用于快速查找一些之前时间线上偶然看到的、现在却找不到的 status,以及自己过去的某些 status,我觉得已经足够了。

安装

本文指令未特别提示的情况下全部使用 sudo 用户进行。

  1. 安装依赖
sudo apt-get install -y postgresql-server-dev-all
sudo apt-get install -y gcc
sudo apt-get install -y icu-devtools libicu-dev

使用 Debian 与 Ubuntu 外的系统请自行更换指令。

  1. 下载拓展包
sudo git clone https://github.com/huangjimmy/pg_cjk_parser.git

假设目前操作的用户为 user ,拓展包目录为 /home/user/pg_cjk_parser ,进入这个目录

cd /home/user/pg_cjk_parser
  1. 安装拓展
sudo make clean && make install

(抱歉之前这里忘记加上 sudo 了!)

  1. 以 postgres 用户身份访问终端 psql
sudo -u postgres psql
  1. 连接 pleroma 数据库
\c pleroma;
  1. 创建拓展 pg_cjk_parser
CREATE EXTENSION pg_cjk_parser;
  1. 配置搜索并设置为默认
CREATE TEXT SEARCH PARSER public.pg_cjk_parser (
    START = prsd2_cjk_start,
    GETTOKEN = prsd2_cjk_nexttoken,
    END = prsd2_cjk_end,
    LEXTYPES = prsd2_cjk_lextype,
    HEADLINE = prsd2_cjk_headline);

CREATE TEXT SEARCH CONFIGURATION public.config_2_gram_cjk (
    PARSER = pg_cjk_parser
);

SET default_text_search_config = 'public.config_2_gram_cjk';
  1. 测试效果
SELECT alias, description, token FROM 
ts_debug('Doraemnon Nobita「ドラえもん のび太の牧場物語」多拉A梦 野比大雄χΨψΩω https://www.doraemon.com/welcome.html');
  1. 设置映射
ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR asciihword
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR cjk
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR email
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR asciiword
    WITH english_stem;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR entity
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR file
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR float
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR host
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR hword
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR hword_asciipart
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR hword_numpart
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR hword_part
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR int
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR numhword
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR numword
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR protocol
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR sfloat
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR tag
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR uint
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR url
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR url_path
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR version
    WITH simple;

ALTER TEXT SEARCH CONFIGURATION public.config_2_gram_cjk
    ADD MAPPING FOR word
    WITH simple;
  1. 再次测试
SELECT to_tsvector('Doraemnon Nobita「ドラえもん のび太の牧場物語」多拉A梦 野比大雄χΨψΩω'), to_tsquery('のび太'), 
to_tsquery('野比大雄'),
to_tsvector('Doraemnon Nobita「ドラえもん のび太の牧場物語」多拉A梦 野比大雄χΨψΩω') @@ to_tsquery('のび太'),
to_tsvector('Doraemnon Nobita「ドラえもん のび太の牧場物語」多拉A梦 野比大雄χΨψΩω') @@ to_tsquery('野比大雄');
  1. 修改 postgresql.conf
sudo nano /etc/postgresql/11/main/postgresql.conf

11 是我的 postgresql 版本号,如果版本不同,替换为您所用的版本号即可。

按键 Ctrl + W 并输入 shared_preload_libraries 跳转到该配置所在行,修改引号内内容为 pg_cjk_parser.so

  1. 更新 Pleroma 的搜索配置和索引
sudo -Hu pleroma -s $SHELL -lc "./bin/pleroma_ctl database set_text_search_config public.config_2_gram_cjk"

根据数据库大小差异等待时间也有长有短,期间可能出现 ”NOTICE: word is too long to be indexed DETAIL: Words longer than 2047 characters are ignored.“ 不用管它。跑完后结果会显示 “UPDATE XXX”。

如果之前安装了 RUM 索引,这个命令可能会执行失败,报错大概这个样子:

** (DBConnection.ConnectionError) tcp recv: closed (the connection was closed by the pool, possibly due to a timeout or because the pool has been terminated) lib/ecto/adapters/sql.ex:760: Ecto.Adapters.SQL.raise_sql_call_error/1 lib/mix/tasks/pleroma/database.ex:218: [Mix.Tasks.Pleroma.Database.run/1](https://Mix.Tasks.Pleroma.Database.run/1) (stdlib [3.12.1.2](https://3.12.1.2)) erl_eval.erl:680: :erl_[eval.do](https://eval.do)_apply/6 (elixir 1.10.4) lib/code.ex:341: Code.eval_string_with_error_handling/3

如果出现这种情况,需要手动去跑下卡住的那行命令。

sudo -u postgres psql
\c pleroma;
UPDATE objects SET updated_at = NOW();

可能要等待较长一段时间,更新完毕后会有 ”UPDATE XXX“ 的提示。(参考: UPDATE 4406338 等了三十分钟左右)

  1. 重启 postgrsql 服务
sudo systemctl restart postgresql

理论上 postgresql 和 pleroma 二选一进行重启即可,由于上面变动了 shared_preload_libraries 需要重启 postgresql 。之后搜索便更新完毕了,试着在实例搜索框搜索看下效果如何。

参考链接

  1. https://wiki.iroiro.party/doku.php?id=pleroma:zh-search