二、PostgerSQL全文检索系统之中文支持
从前一节PostgreSQL全文检索系统之基本介绍可以看出全文检索有4个基本功能(文本匹配,文本解析,文本排序,文本高亮),同时不支持中文。
2.1 安装zhparser中文插件
zhparser是一款中文分词的PostgreSQL插件。我使用过,效果不错,故推荐。zhparser只是一个PostgreSQL扩展插件,它是基于SCWS的(一个简易中文分词系统,Simple Chinese Word Segmentation)。
第一步,安装SCWS
# 下载并解压
wget -q -O - http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 | tar xvjf -
# 编译安装
cd scws-1.2.3 ; ./configure ; sudo make install
第二步,编译和安装zhparser
# 先安装PostgreSQL的扩展包
sudo apt-get install postgresql-server-dev-10
git clone https://github.com/amutu/zhparser.git
cd zhparser
SCWS_HOME=/usr/local make && sudo make install
可加自定义词典
自定义词库,labeldict.txt 如下:
腾讯 1.0 1.0 @
C++ 1.0 1.0 !
中国人 1.0 1.0 !
就是 1.0 1.0 !
1.每行由4个字段组成,依次为“词语"(由中文字或3个以下的字母合成), “TF”, “IDF”, “词性”, 字段之间用空格或制表符分开,数量不限 (注意,发现如果字段之间用空格隔开,然后用scws官方的php程序将txt词库转换xdb后,词库无效,但是txt词库有效,所以为了兼容性,字段之间最好仅用一个制表符分隔,且注意txt文件的编码要与程序要使用的编码一致)
2.词性设为“!“,则表示该词设为无效,即使在其它核心库中存在该词也视为无效
scws 自带的可以将txt文件转xdb文件
scws-gen-dict -i /usr/share/postgresql/10/tsearch_data/labeldic.txt -o /usr/share/postgresql/10/tsearch_data/labeldic.xdb -c utf-8
第三步,进入数据库安装扩展
# 进入数据库
sudo -u postgres psql
# 连接数据库
# 安装扩展
CREATE EXTENSION zhparser;
CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;
2.2 使用
接下来我们来测试一下,是不是按照我们的意愿来分词。
postgres=# SELECT to_tsvector('testzhcfg','粤ICP备15004902号-2');
to_tsvector
----------------------------------------------------------------------------------------------------------------
'15004902':4 'icp':2
(1 row)
理想的结果为 ‘15004902’:4 ‘icp’:2 ‘号’:5 ‘备’:3 ‘粤’:1
注意点:如果 SELECT to_tsvector(‘testzhcfg’,‘粤ICP备15004902号-2’)为空或者不全,则运行:
SELECT ts_debug('testzhcfg', '粤ICP备15004902号-2');
ts_debug
--------------------------------------------------------------------------------------------------------------
(x,"unknown,未知词",粤,{simple},simple,{粤})
(e,"exclamation,感叹词",ICP,{simple},simple,{icp})
(x,"unknown,未知词",备,{simple},simple,{备})
(e,"exclamation,感叹词",15004902,{simple},simple,{15004902})
(x,"unknown,未知词",号,{simple},simple,{号})
(u,"auxiliary,助词",-,{},,)
(e,"exclamation,感叹词",2,{simple},simple,{2})
ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR x WITH simple;
丢失的词是因为之前并没有为x创建token映射。现在加上x的token映射,就可以了。
还可以这样使用。
postgres=# SELECT ts_parse('zhparser','粤ICP备15004902号-2');
(120,粤)
(101,ICP)
(120,备)
(101,15004902)
(120,号)
(117,-)
(101,2)
建议初始 zhparser.multi_short=on 设置为on。
postgres=# set zhparser.multi_short=on;
SET
postgres=# select to_tsvector('testzhcfg','南京人民政府');
to_tsvector
-----------------------------------------
'人民':3 '人民政府':2 '南京':1 '政府':4
通过下面这条语句来使分词时忽略标点符号的影响
postgres=# alter role all set zhparser.punctuation_ignore=on;
2.3 安装jieba中文插件
git clone https://github.com/jaiminpan/pg_jieba
cd pg_jieba && \
git submodule update --init --recursive && \
mkdir pg_jieba/build && \
cd pg_jieba/build &&\
cmake -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/10/server .. && \
make && make install
jieba=# create extension pg_jieba;
CREATE EXTENSION
jieba=# select * from to_tsquery('jiebacfg', '是拖拉机学院手扶拖拉机专业的。不用多久,我就会升职加薪,当上CEO,走上人生巅峰。');
to_tsquery
-----------------------------------------------------------------------------------------------
'拖拉机' & '学院' & '手扶拖拉机' & '专业' & '不用' & '多久' & '会' & '升职' & '加薪' & '当上'
(1 row)
jieba=# select * from to_tsvector('jiebacfg', '是拖拉机学院手扶拖拉机专业的。不用多久,我就会升职加薪,当上CEO,走上人生巅峰。');
to_tsvector
-----------------------------------------------------------------------------------------------------
'不用':8 '专业':5 '会':13 '加薪':15 '升职':14 '多久':9 '学院':3 '当上':17 '手扶拖拉机':4 '拖拉机':2
(1 row)
jieba 加有用词典
云计算
韩玉鉴赏
蓝翔 nz
区块链 10 nz
cd /PATH/TO/POSTGRESQL_INSTALL/share/postgresql/tsearch_data
OR
cd /PATH/TO/POSTGRESQL_INSTALL/share/tsearch_data
cp 'YOUR DICTIONARY' jieba_user.dict
详情见jieba github
2.4 pg同义词词典
CREATE TEXT SEARCH DICTIONARY my_synonym (
TEMPLATE = synonym,
SYNONYMS = my_synonyms
);
ALTER TEXT SEARCH CONFIGURATION testzhcfg ALTER MAPPING FOR n,v,a,i,e,l,x WITH my_synonym,simple;
#CREATE TEXT SEARCH CONFIGURATION dxp_name (COPY = simple);
#ALTER TEXT SEARCH CONFIGURATION dxp_name ALTER MAPPING FOR n,v,a,i,e,l,x WITH my_synonym;
postgres=# SELECT ts_lexize('my_synonym','indices');
ts_lexize
-----------
{index}
(1 row)
synonym模版要求的唯一的参数是SYNONYMS,这是它的配置文件的基础名称—上面例子中my_synonyms。 文件的全名为$SHAREDIR/tsearch_data/my_synonyms.syn($SHAREDIR是PostgreSQL安装的共享数据目录)。 文件格式是每一行的每个字被取代,带有这个词的同义词,用空格分隔。忽略空白行和空格。如下:
bob robert
bobby robert
alan al
albert al
allen al