一、PostgreSQL全文检索系统之基本介绍

一、全文检索系统之基本介绍

1.1 PostgreSQL的文本匹配

PostgreSQL中的全文搜索基于匹配算子@@,如果一个tsvector(document)匹配一个tsquery(query), 则返回true。

postgres=# SELECT 'hello world hfpp2012'::tsvector @@ 'hello'::tsquery;
postgres=# SELECT 'hello'::tsquery @@ 'hello world hfpp2012'::tsvector;

两种写法,输出的结果都是这样的。

 ?column? 
----------
 t
(1 row)

t就是true,说明是匹配成功的。如果是f,那就是false,表示匹配不成功。

来搜索中文的试下

postgres=# SELECT '号'::tsquery @@ '粤ICP备15004902号-2'::tsvector;
 ?column? 
----------
 f
(1 row)

显然,默认情况下,对中文是不支持的。

下面是一个最简单的人门例子

select title from articles where to_tsvector('english', body) @@ to_tsquery('english', 'ruby')
                        title                        
-----------------------------------------------------
 最简单的用户登录注册系统
 登录认证系统的进阶使用
 用OneAPM作为你的监控平台  
 使用backup来备份数据库
 使用mina来部署ruby on rails应用
 Mina的进阶使用
 用logrotate切割Ruby on rails日志
 用exception_notification结合Slack或数据库来捕获异常
 devise简单入门教程
(9 rows)

上面是搜索了articles表中body字段,只要包含ruby的都找出来。这不是where like,而是先将body分成一个个词,之后再来找的。

上面的是没有建立索引的情况下操作的,那样肯定不行的,如果数据量大,会很慢。

CREATE INDEX articles_idx ON articles USING gin(to_tsvector('english', body));

1.2 postgresql 解析文档

要查看一段文本是怎么被PostgreSQL分词的,可以用to_tsvector这个指令,是这样使用的。

postgres=# SELECT to_tsvector('english', 'a fat  cat sat on a mat - it ate a fat rats');
                     to_tsvector                     
-----------------------------------------------------
 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4
(1 row)
postgres=# SELECT to_tsvector( '粤ICP备15004902号-2');
                     to_tsvector                     
-----------------------------------------------------
'-2':2 '粤icp备15004902号':1
(1 row)

可以看出默认情况下,对中文是不分词的。

1.3 postgresql 搜索结果排名(Ranking Search Results)

就是使用ts_rank或ts_rank_cd按照匹配词的出现次数做个排名。
例如:

postgres=# select title, ts_rank(to_tsvector('english', body), to_tsquery('english', 'ruby')) AS rank from articles where to_tsvector('english', body) @@ to_tsquery('english', 'ruby')
order by rank desc;
                        title                        |   rank    
-----------------------------------------------------+-----------
 使用mina来部署ruby on rails应用                     | 0.0928561
 登录认证系统的进阶使用                              | 0.0906656
 devise简单入门教程                                  | 0.0889769
 用exception_notification结合Slack或数据库来捕获异常 | 0.0889769
 Mina的进阶使用                                      | 0.0865452
 使用backup来备份数据库                              | 0.0827456
 用logrotate切割Ruby on rails日志                    | 0.0759909
 用OneAPM作为你的监控平台                            | 0.0759909
 ruby                                                | 0.0607927
(9 rows)

1.4 postgresql 结果的高亮(Highlighting Results)

有时候你需要把搜索的关键词高亮起来,就像谷歌,百度那样,PostgreSQL默认就支持的。
PostgreSQL有一个指令ts_headline就是来做这个事情的。ts_headline使用起来也简单,看下面的例子:

postgres=# select title,ts_headline('testzhcfg', title, to_tsquery('testzhcfg', 'mina')), ts_rank(to_tsvector('testzhcfg', title), to_tsquery('testzhcfg', 'mina')) AS rank from articles where to_tsvector('testzhcfg', body) @@ to_tsquery('testzhcfg', 'mina')
order by rank;
              title              |             ts_headline              |   rank    
---------------------------------+--------------------------------------+-----------
 使用mina来部署ruby on rails应用 | 使用<b>mina</b>来部署rubyonrails应用 | 0.0607927
 Mina的进阶使用                  | <b>Mina</b>的进阶使用                | 0.0607927
(2 rows)

高亮的地方就用包住了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值