Coding 的痕迹

一位互联网奔跑者的网上日记

0%

在 PostgreSQL 中配置中文分词 zhparser

背景

想将校园网上的文章、通知和附件缓存到本地,通过数据库的全文检索查找其中内容,并决定使用 PostgreSQL 来实现。略检索了一下有关资料,主要有 pg_jiebazhparser 两个中文分词库。这里我们就是用 zhparser

主要的软件和版本如下:

  • PostgreSQL 13
  • scws-1.2.3
  • zhparser (master分支版本)

安装过程

安装 scws

安装过程以 zhparser - Github 为指导进行。首先安装依赖 scws-1.2.3

1
2
3
wget -q -O - http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 | tar xf -

cd scws-1.2.3 ; ./configure ; make install

但是我在解压过程中:

1
2
3
4
root@KiteAgentEnv:~# tar xf scws-1.2.3.tar.bz2
bzip2: (stdin) is not a bzip2 file.
tar: Child returned status 2
tar: Error is not recoverable: exiting now

多次尝试无果,便在 Windows 下解压好拷贝过去了。

make install 的时候,报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@KiteAgentEnv:~/scws-1.2.3# make install
cd . && /bin/bash /root/scws-1.2.3/missing automake-1.15 --gnu
/root/scws-1.2.3/missing: line 81: automake-1.15: command not found
WARNING: 'automake-1.15' is missing on your system.
You should only need it if you modified 'Makefile.am' or
'configure.ac' or m4 files included by 'configure.ac'.
The 'automake' program is part of the GNU Automake package:
<http://www.gnu.org/software/automake>
It also requires GNU Autoconf, GNU m4 and Perl in order to run:
<http://www.gnu.org/software/autoconf>
<http://www.gnu.org/software/m4/>
<http://www.perl.org/>
make: *** [Makefile:335: Makefile.in] Error 1

才意识到 automake 是依赖具体版本的。尝试使用 apt 安装,但是版本不对。 为了方便,安装对应的版本:

1
2
3
4
5
6
7
wget https://mirrors.tuna.tsinghua.edu.cn/gnu/automake/automake-1.15.tar.gz

tar -zxvf automake-1.15.tar.gz

cd automake-1.15
./configure
sudo make && make install

再在 scws 目录执行 make install 就好了

安装 zhparser

1
2
3
git clone https://github.com/amutu/zhparser.git

make && make install

在编译过程中,报错提示:找不到 postgres.h

1
2
3
4
5
6
7
root@KiteAgentEnv:~/code/zhparser# make && make install
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer -fPIC -I/usr/local/include/scws -I. -I./ -I/usr/include/postgresql/13/server -I/usr/include/postgresql/internal -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2 -c -o zhparser.o zhparser.c
zhparser.c:10:10: fatal error: postgres.h: No such file or directory
10 | #include "postgres.h"
| ^~~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: zhparser.o] Error 1

首先考虑的是:是不是没有安装相关的开发包?尝试使用 apt 安装:

1
apt install libpq-dev

再次编译发现错误依旧。在报错中,找到 -I 参数包含的路径 /usr/include/postgresql 发现确实没有这个文件。而使用命令 dpkg -L libpq-dev 发现 libpq-dev 确实安装到该路径下的。继续搜索,受 StackOverflow 一个提问(参考资料2)的启发,执行:

1
apt install postgresql-server-dev-13

不过这个包依赖了很多 llvm、clang、python3 的包,有些臃肿。(如果提示找不到,可以尝试参考 官方 Wiki 添加 apt 源)这时候再看,postgres.h 就存在了。好多文章中未提到这一点,不知为何我系统中的头文件缺失。

安装完后,在 IDE 中创建扩展:

1
2
3
4
CREATE EXTENSION zhparser;

CREATE TEXT SEARCH CONFIGURATION zh_cfg (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION zh_cfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;

初步的配置就完成了。最后一条命令中的 n,v,a,i,e,l 指的是单词的词性,可以使用下面这句 SQL 查看:

1
SELECT ts_token_type('zhparser');

zhparser 支持多种词性分析,简单选取几行结果:

1
2
3
4
5
6
"(97,a,""adjective,形容词"")"
"(98,b,""differentiation,区别词"")"
"(99,c,""conjunction,连词"")"
"(100,d,""adverb,副词"")"
"(101,e,""exclamation,感叹词"")"
"(102,f,""position,方位词"")"

测试

在使用全文检索前,可以翻阅官方文档(参考资料3),对接口有一个初步的了解。

1
SELECT * FROM ts_parse('zhparser', '2010年保障房建设在全国范围内获全面启动,从中央到地方纷纷加大了保障房的建设和投入力度 。2011年,保障房进入了更大规模的建设阶段。住房城乡建设部党组书记、部长姜伟新去年底在全国住房城乡建设工作会议上表示,要继续推进保障性安居工程建设。');

查询结果:

1
2
3
4
5
6
7
101,2010
113,年
118,保障
110,房建
118,设在
110,全国
...

可以看到,默认参数下的分词有一些问题,这将在后续进一步调整、优化。

还有其他几个 SQL 语句:

1
2
3
4
5
6
7
8
-- 创建索引
CREATE INDEX idx_gin_page_content
ON public.pages
USING GIN(to_tsvector('zh_cfg', content));

-- 检索
SELECT host || path, title, content FROM public.pages
WHERE to_tsvector('kite_web', content) @@ to_tsquery('zh_cfg', '教学质量');

后记

在参考资料4 中,作者提出了一些分词问题,并罗列出不少的参考资料,值得深入研究。在查看这篇博文时,《信息检索导论》中提到的理论仿佛又在眼前出现,改日确实应该再捧起来把它读完。

参考资料

  1. 安装指定版本的automake, CSDN
  2. How to fix ‘postgres.h’ file not found problem?, StackOverflow
  3. 第 12 章 全文搜索, PostgreSQL 文档
  4. PostgreSQL的全文检索插件zhparser的中文分词效果, ChinaUnix.net

欢迎关注我的其它发布渠道