使用Postgres和pg_search gem全文搜索Ruby on Rails应用程序

时间:2012-06-25 17:51:25

标签: ruby-on-rails postgresql indexing full-text-search pg-search

我已在pg_search的Google群组中发布此查询:

https://groups.google.com/forum/?fromgroups#!topic/casecommons-dev/3tbCthkDHg0

但没有回复,所以我在StackOverflow上发布它。我的问题是:在以下情况下使用pg_search gem时,我应该创建GIN类型索引吗?

我的搜索仅限于使用pg_search_scope在单个模型中进行搜索。

这是一个具体的例子:

class Scenario < ActiveRecord::Base
   ...
   include PgSearch
  pg_search_scope :search, :against => [:name, :compute_ngls],
   :using => { :tsearch => {:dictionary => "english"} }


   def self.text_search(query)
     if query.present?
       search(sanitize(query))
     else
       scoped
     end
   end
  ...
end

对text_search方法的调用如下:

  scenarios = scenarios.text_search(params[:sSearch])

我在某些列上只有常规的btree索引,例如:name。我没有杜松子酒或吉斯特索引。我的问题是:我应该明确创建这些索引吗?如果是,那么哪种列和哪些列?你能告诉我创建这些索引的语法吗?

1 个答案:

答案 0 :(得分:0)

关于是否创建索引的问题不是人们可以通过查看您的Ruby代码而知道的,也可能无法知道查看您的数据库模式。问题取决于查询的选择性,索引的数据量以及表的页面大小。这是因为PostgreSQL表支持物理顺序扫描,如果检索到表的很大一部分,这些扫描通常比索引驱动的查找更快。

GIN和GiST索引将帮助您进行全文搜索,而btree则不是特别有用,但为了使它们有用,您必须索引相当大的表并仅拉动该表的一小部分。

我对此的偏好是等待有性能原因来创建索引,而不是在有疑问时预先创建。

修改

最近重读GIN与全文搜索有关,这使我转而反复上述建议。我现在相信专门针对全文索引,你最好先创建GIN索引然后在它干扰性能时丢弃它。

请注意,GIN具有主要的写入开销,因此它绝对不是免费的。但是,如果fts是应用程序中的主要用例,则FTS索引几乎总是具有足够的选择性。