二、PostgerSQL全文检索系统之中文支持

二、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

你可能感兴趣的:(postgres)