UXDB支持全文检索,其内置的缺省的分词解析器采用空格分词。因为一般英语等语言分词比较简单,按照标点、空格切分语句即可获得有含义的词语,UXDB自带的解析器就是按照此原理来分词的。而中文比较复杂,词语之间没有空格分割,长度也不固定,分词有时还跟语句的语义相关,因此自带的解析器不能进行中文分词。
要支持中文的全文检索需要额外的中文分词插件,zhparser是基于简易中文分词系统实现的一个插件。zhparser用C语言实现了UXDBTEXT SEARCH PARSER需要的接口,这些接口会调用SCWS中文分词引擎进行分词。使用zhparser这个插件,便可以使UXDB支持中文分词,继而可以使用UXDB支持中文全文检索。
中文全文检索应用
01
测试解析器
uxdb=# SELECT * FROM ts_parse('zhparser', 'hello world!
2010年保障房建设在全国范围内获全面启动,从中央到地方纷纷加大了保障房的建设和投入力度。2011年,保障房进入了更大规模的建设阶段。住房城乡建设部党组书记、部长姜伟新去年底在全国住房城乡建设工作会议上表示,要继续推进保障性安居工程建设。’);
tokid | token
-------+----------
101 | hello
101 | world
117 | !
101 | 2010
113 | 年
118 | 保障
110 | 房建
118 | 设在
110 | 全国
110 | 范围
......
02
测试tsvector转化
uxdb=# SELECT to_tsvector('testzhcfg','南京市长江大桥'); to_tsvector
-------------------------
'南京市':1 '长江大桥':2
03
测试tsquery转化
uxdb=# SELECT to_tsquery('testzhcfg', '保障房资金压力'); to_tsquery
---------------------------------
'保障' & '房' & '资金' & '压力'
04
测试查询
uxdb=# SELECT to_tsvector('testzhcfg','中华人民共和国中国'); to_tsvector
----------------------------------
'中华人民共和国':1 '中国':2uxdb=# SELECT to_tsvector('testzhcfg','中华人民共和国中国') @@ '中' :: tsquery; ?column?
----------
f
uxdb=# SELECT to_tsvector('testzhcfg','中华人民共和国中国') @@ '人民' :: tsquery; ?column?
----------
f
uxdb=# SELECT to_tsvector('testzhcfg','中华人民共和国中国') @@ '中国' :: tsquery;?column?
----------
应用中文全文检索
01
简单查询
查询中可以使用最简单的SELECT * FROM table WHERE to_tsvector(‘parser_name’, field) @@‘word’;来查询field字段分词中带有word一词的数据:
uxdb=# CREATE TABLE table_a(name text);
uxdb=# INSERT INTO table_a values('中华人民共和国中国');
uxdb=# INSERT INTO table_a values('我们都是中国人');
uxdb=# SELECT * FROM table_a WHERE to_tsvector('testzhcfg', name) @@ '中国人';
name
----------------
我们都是中国人
使用 to_tsquery() 方法将句子解析成各个词的组合向量,当然也可以使用&(AND)、(OR)和!(NOT)符号拼接自己需要的向量;在查询长句时,可以使用
SELECT * FROM table WHERE to_tsvector(‘parser_name’, field) @@ to_tsquery(‘parser_name’,‘words’):
uxdb=# SELECT * FROM table_a WHERE to_tsvector('testzhcfg', name) @@
to_tsquery('testzhcfg','中国|中国人');
name --------------------
中华人民共和国中国
我们都是中国人
如果想像MySQL的SQL_CALC_FOUND_ROWS语句一样同步返回结果条数,则可以使用 SELECT COUNT(*) OVER() AS score FROM table WHERE …,UXDB会在每一行数据添加score字段存储查询到的总结果条数:
uxdb=# SELECT COUNT(*) OVER() AS score FROM table_a WHERE
to_tsvector('testzhcfg',name)@@to_tsquery('testzhcfg','中国人');
score
------- 1
02
简存储分词结果
使用一个字段来存储分词向量,并在此字段上创建索引来更优地使用分词索引:
uxdb=# ALTER TABLE table_a ADD COLUMN tsv_column tsvector; // 添加一个分词字段。
uxdb=# UPDATE table_a SET tsv_column = to_tsvector(‘testzhcfg’, coalesce(name,’’)); // 将字段的分词向量更新到新字段中。
uxdb=# CREATE INDEX idx_gin_zhcn ON table_a USING GIN(tsv_column); // 在新字段上创建GIN索引。
CREATE TRIGGER trigger_a BEFORE INSERT OR UPDATE ON table_a FOR EACH ROW
EXECUTE PROCEDURE tsvector_update_trigger( tsv_column, ‘testzhcfg’, name); // 创建更新分词触发器。
这样,再进行查询时就可以直接使用分词结果,例如SELECT * FROM table_a WHERE
tsv_column @@ ‘中国人’;。
需要注意,这时候在往表内插入数据的时候,可能会报错,提示指定parser_name的 schema,这时候可以使用\dF命令查看所有text search configuration的参数:
uxdb=# \dF
文本搜索组态列表
架构模式 | 名称 | 描述
------------±-----------±--------------------------------------
public | testzhcfg |
ux_catalog | danish | configuration for danish language
ux_catalog | dutch | configuration for dutch language
ux_catalog | english | configuration for english language
ux_catalog | finnish | configuration for finnish language
ux_catalog | french | configuration for french language
ux_catalog | german | configuration for german language
ux_catalog | hungarian | configuration for hungarian language
ux_catalog | italian | configuration for italian language
ux_catalog | norwegian | configuration for norwegian language
ux_catalog | portuguese | configuration for portuguese language
ux_catalog | romanian | configuration for romanian language
ux_catalog | russian | configuration for russian language
ux_catalog | simple | simple configuration
ux_catalog | spanish | configuration for spanish language
ux_catalog | swedish | configuration for swedish language
ux_catalog | turkish | configuration for turkish language
注意:schema参数,在创建trigger时需要指定schema,如上面,就需要使用public.testzhcfg。
-FIN-
D