PostgreSQL chinese full text search 中文全文检索
背景
首先要感谢amutu以及其他为中文检索贡献的兄弟们, 我在之前写过一些关于PG中文全文检索的文章, 比较繁琐.
《PostgreSQL 使用 nlpbamboo chinesecfg 中文分词》
使用amutu的zhparser就比较方便了, 分词的部署比以前简单很多. 具体可参看amutu 的BLOG,
http://amutu.com/blog/zhparser/
zhparser
zhparser是什么
zhparser是一个PostgreSQL中文分词的插件,通过它,可以使PostgreSQL支持中文的全文检索(Full Text Search)。
为什么需要zhparser
一般英语等语言分词比较简单,按照标点、空格切分语句即可获得有含义的词语,PostgreSQL自带的parser就是按照这个原理来分词的,比较简单。而中文就比较复杂,词语之间没有空格分割,长度也不固定,怎么分词有时还跟语句的语义有关,因此PG自带的parser不能用来做中文分词。使用zhparser这个插件,便可以使PG支持中文分词,继而可以使用PG做中文全文检索。
zhparser原理是什么
zhparser用C语言实现了PostgreSQL TEXT SEARCH PARSER需要的接口,这些接口会调用SCWS中文分词引擎进行分词。
我这里在CentOS 6.x x64和PostgreSQL 9.3.3上面测试了一下, 非常好用.
# wget http://www.xunsearch.com/scws/down/scws-1.2.2.tar.bz2
# tar -jxvf scws-1.2.2.tar.bz2
# cd scws-1.2.2
# ./configure --prefix=/opt/scws-1.2.2
# make
# make install
# git clone https://github.com/amutu/zhparser.git
# cd zhparser/
[root@db-172-16-3-150 zhparser]# export PATH=/home/pg93/pgsql/bin:$PATH
[root@db-172-16-3-150 zhparser]# which pg_config
/home/pg93/pgsql/bin/pg_config
# SCWS_HOME=/opt/scws-1.2.2 make
# make install
[root@db-172-16-3-150 zhparser]# su - pg93
pg93@db-172-16-3-150-> psql
psql (9.3.3)
Type "help" for help.
digoal=# create extension zhparser;
CREATE EXTENSION
digoal=# select * from pg_ts_parser ;
prsname | prsnamespace | prsstart | prstoken | prsend | prsheadline | prslextype
----------+--------------+-------------+-----------------+-----------+---------------+---------------
default | 11 | prsd_start | prsd_nexttoken | prsd_end | prsd_headline | prsd_lextype
zhparser | 25956 | zhprs_start | zhprs_getlexeme | zhprs_end | prsd_headline | zhprs_lextype
(2 rows)
digoal=# CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
CREATE TEXT SEARCH CONFIGURATION
digoal=# select * from pg_ts_config where cfgname='testzhcfg';
cfgname | cfgnamespace | cfgowner | cfgparser
-----------+--------------+----------+-----------
testzhcfg | 25956 | 10 | 26134
(1 row)
配置token type, 参考http://www.postgresql.org/docs/9.3/static/textsearch-parsers.html
digoal=# ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;
ALTER TEXT SEARCH CONFIGURATION
digoal=# select * from pg_ts_config_map where mapcfg=(select oid from pg_ts_config where cfgname='testzhcfg');
mapcfg | maptokentype | mapseqno | mapdict
--------+--------------+----------+---------
26135 | 97 | 1 | 3765
26135 | 101 | 1 | 3765
26135 | 105 | 1 | 3765
26135 | 108 | 1 | 3765
26135 | 110 | 1 | 3765
26135 | 118 | 1 | 3765
(6 rows)
SELECT * FROM ts_parse('zhparser', 'hello world! 2010年保障房建设在全国范围内获全面启动,从中央到地方纷纷加大 了 保 障 房 的 建 设
和 投 入 力 度 。2011年,保障房进入了更大规模的建设阶段。住房城乡建设部党组书记、部长姜伟新去年底在全国住房城乡建设工作会议上表示,
要继续推进保障性安居工程建设。');
tokid | token
-------+----------
101 | hello
101 | world
117 | !
101 | 2010
113 | 年
118 | 保障
110 | 房建
118 | 设在
110 | 全国
110 | 范围
102 | 内
118 | 获
97 | 全面
118 | 启动
117 | ,
110 | 从中
118 | 央
118 | 到
110 | 地方
100 | 纷纷
118 | 加大
118 | 了
118 | 保
110 | 障
110 | 房
117 | 的
118 | 建
118 | 设
99 | 和
118 | 投
118 | 入
110 | 力
107 | 度
117 | 。
101 | 2011
113 | 年
117 | ,
118 | 保障
110 | 房
118 | 进入
118 | 了
100 | 更
110 | 大规模
117 | 的
118 | 建设
110 | 阶段
117 | 。
110 | 住房
110 | 城乡建设
110 | 部党组
110 | 书记
117 | 、
110 | 部长
110 | 姜伟新
116 | 去年底
112 | 在
110 | 全国
110 | 住房
110 | 城乡建设
118 | 工作
110 | 会议
110 | 上表
118 | 示
117 | ,
118 | 要
118 | 继续
118 | 推进
110 | 保障性
118 | 安居
110 | 工程建设
117 | 。
(71 rows)
SELECT to_tsvector('testzhcfg','“今年保障房新开工数量虽然有所下调,但实际的年度在建规模以及竣工规模会超以往年份,相对应的对资金的需
求也会创历史纪录。”陈国强说。在他看来,与2011年相比,2012年的保障房建设在资金配套上的压力将更为严峻。');
to_tsvector
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'2011':27 '2012':29 '上':35 '下调':7 '严峻':37 '会':14 '会创':20 '保障':1,30 '历史':21 '压力':36 '国强':24 '在建':10 '实际':8 '对应':17 '年份':16 '年度':9 '开工':4 '房':2 '房建':31 '数量':5 '新':3 '有所':6 '相比':28 '看来':26 '竣工':12 '纪录':22 '规模':11,13 '设
在':32 '说':25 '资金':18,33 '超':15 '配套':34 '陈':23 '需求':19
(1 row)
SELECT to_tsquery('testzhcfg', '保障房资金压力');
to_tsquery
---------------------------------
'保障' & '房' & '资金' & '压力'
(1 row)
参考
1. http://pgxn.org/dist/zhparser/
2. https://github.com/hightman/scws
3. http://amutu.com/blog/zhparser/
4. http://www.xunsearch.com/scws/
5. 《PostgreSQL 使用 nlpbamboo chinesecfg 中文分词》
6. http://www.tudou.com/programs/view/X2U9f0s04h0
7. http://www.postgresql.org/docs/9.3/static/catalog-pg-ts-config-map.html
8. http://www.postgresql.org/docs/9.3/static/sql-altertsconfig.html
9. http://www.postgresql.org/docs/9.3/static/textsearch-parsers.html