PostgreSQL全文搜索,基于RUM索引和zhparser分词

介绍

RUM扩展安装

第一步,从GitHub拉取代码

1
2
3
git clone https://github.com/postgrespro/rum
# 如果“网速慢”,使用下面方式拉取
git clone https://mirror.ghproxy.com/https://github.com/postgrespro/rum

第二步,进入目录并make

1
2
3
4
5
cd rum
make USE_PGXS=1
make USE_PGXS=1 install
make USE_PGXS=1 installcheck
psql DB -c "CREATE EXTENSION rum;"

可能遇到的问题:

  1. Makefile:40: /usr/lib/postgresql/*/pgxs.mk: No such file or directory 解决方式:添加pgsqlbinPATH export PATH="/usr/local/pgsql/bin/:$PATH"
  2. 修改了pgsql的默认端口,会在installcheck这一步出现以下错误: psql: error: connection to server on socket 处理方式: make USE_PGXS=1 installcheck => make USE_PGXS=1 installcheck -p XXXX
  3. psql DB -c "CREATE EXTENSION rum;" 这一步,需要提前su - postgres
  4. psql DB -c "CREATE EXTENSION rum;"DB请替换成你的实际数据库名称
  5. psql DB -c "CREATE EXTENSION rum;"如果修改了端口,需要改成psql DB -c "CREATE EXTENSION rum;" -p xxxx

返回CREATE EXTENSION则扩展安装成功

RUM索引的创建和使用

索引创建两种方式:

  1. 创建一个tsvector类型的字段,通过zhparser分词插件和TRIGGER ,将需要全文索引的内容进行处理后存储到该字段。 这个方法无法使用一些RUM的其他特性,不推荐
  2. 创建索引的时候,使用to_tsvector来创建指定列的索 字段类型选择:tsvector

使用步骤

第一步

创建tsvector 类型的字段,这边字段名创建的为:idx

第二步

1
CREATE TRIGGER tsvectorupdate BEFORE UPDATE OR INSERT ON table_name FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('idx', 'public.zhcfg', 'column1', 'column2');

使用上述SQL创建一个Trigger,用于自动生成idx列内容。

第三步

idx创建RUM索引

1
CREATE INDEX tsts_idx ON tsts USING rum (t);

其他的索引用法,可以使用RUM的一些特性,创建多字段合并索引

比如:rum_tsvector_addon_ops,该操作符用于tsvector类型的字段。

1
2
CREATE INDEX tsts_idx ON tsts USING rum (idx rum_tsvector_addon_ops, published_time)
    WITH (attach = 'published_time', to = 'idx');

上述SQL的作用是创建一个名为tsts_idx的索引名称给tsts表,并且追加published_timeidx,形成一个多字段的索引。该特性优越于GIN的索引,能够有效解决全文索引+其他字段排序导致的查询慢的问题。 另外,还可以执行以下查询:

1
SELECT id, published_time <=> '2023-05-16 14:21:25' FROM tsts WHERE idx @@ '开源 & 测试' ORDER BY published_time <=> '2023-05-16 14:21:25' LIMIT 5;

上述方式,可以查询特定时间相近的数据。

备注

另外还有一些RUM的其他特性,可以参考官网:https://github.com/postgrespro/rum

缺陷

RUM非官方内置扩展,并且会产生较大的日志、数据文件,占用更多的存储空间。