世界上最伟大的投资就是投资自己的教育

首页PostgreSQL
随风 · 练气

PostgreSQL 的全文检索系统之 pg_search 实现 (四)

随风发布于3658 次阅读

1. 前言 1

pg_search是一个用于PostgreSQL全文检索的 gem,它使用起来简单,功能也很强大。

以本站为例,文章都是放在 articles 这张表中,文章有标题和内容,即 title 和 body,现在要对这两个做全文检索。

2. 安装和使用

安装 gem

gem 'pg_search'

查看pg_search的 readme 文档就可以知道。它主要有两种使用方式,分别是 Multi-search 和 search scopes。Multi-search 是适合于网站比较复杂,例如多张表,要把多张表揉在一起,放到一张表来做查找。现在我们的网站简单,不需要这个功能,所以我们来看看 search scopes 的用法。

class Article < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_or_body, :against => [:title, :body]
end

rails console创建一些文档,之后就能用Article.search_by_title_or_body来搜索了。

这样再结合表单就能实现一个搜索系统的。

3. 其他功能

pg_search还有其他强大的功能。我们来介绍一下。

3.1 关联 (Searching through associations)

我们现在是在 articles 这张上做查询,那是因为我们的网站简单,但有时候是要跨表的,那也很简单。比如,article 是 has_many :tags 的,就可以这样。

class Article < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_or_body,
                  :against => [:title, :body],
                  :associated_against => {
                    :tags => [:name],
                  }
end

可以查看 log 看具体做了什么操作。其实就是 joins 之类。

3.2 字典和中文支持 (dictionary)

这篇文章PostgreSQL 的全文检索系统之中文支持 (三)有介绍PostgreSQL中文支持。

安装好那个中文插件,和 pg_search 结合那太简单了,指定dictionary就好了。

class Article < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_or_body,
                  :against => [:title, :body],
                  :associated_against => {
                    :tags => [:name],
                  },
                  :using => {
                    :tsearch => {:dictionary => "testzhcfg"}
                  }
end
3.3 权重 (Weighting)

可以给需要搜索的项加上优先级,比如,标题要优先于内容。

class Article < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_or_body,
                  :against => {
                    :title => 'A',
                    :body => 'B'
                  },
                  :associated_against => {
                    :tags => [:name],
                  },
                  :using => {
                    :tsearch => {:dictionary => "testzhcfg"}
                  }
end

可以看看日志,如果有类似于"setweight"的输出,说明成功了。

3.4 前缀 (prefix)

假如要搜索一个词,例如 rails,但是忘了怎么拼写,只记得前两个单词,那就是 ra,但输入 ra 时也能找到关于 rails 的文章,这就是前缀的作用。使用也很简单。

class Article < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_or_body,
                  :against => {
                    :title => 'A',
                    :body => 'B'
                  },
                  :associated_against => {
                    :tags => [:name],
                  },
                  :using => {
                    :tsearch => {:dictionary => "testzhcfg", :prefix => true}
                  }
end
3.5 否定 (negation)

否定就是可以搜索不包含的内容,比如! ruby,就是不搜索 ruby,其他的都搜索,一个相反过程啦。

class Article < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_or_body,
                  :against => {
                    :title => 'A',
                    :body => 'B'
                  },
                  :associated_against => {
                    :tags => [:name],
                  },
                  :using => {
                    :tsearch => {:dictionary => "testzhcfg", :prefix => true, :negation => true}
                  }

还有其他各种用法,normalization 用于排序,any_word 是否匹配任何一个,dmetaphone 模糊匹配等。

完结。

本站文章均为原创内容,如需转载请注明出处,谢谢。

0 条回复
暂无回复~~
相关小书
postgresql教程

postgresql教程

postgresql 最全面,最细致的特性介绍与应用教程

发表于

喜欢
我的微信官网服务号精品文章订阅号微信视频号
程序员随风
统计信息
    学员: 22744
    视频数量: 1492
    文章数量: 466

© 汕尾市求知科技有限公司 | 专业版网站 | 关于我们 | 在线学员:1151

粤公网安备 44152102000088号粤公网安备 44152102000088号 | 粤ICP备19038915号

Top