我正在使用pg_search gem来搜索我的应用程序的搜索功能。在添加pg_search之前,我已经在Postgres数据库的表中添加了130,000行数据。现在,当我进行搜索时,需要的时间太长,即大约16000毫秒。
我在PostgreSQL中关注Railscasts Episode343全文搜索
以下是我的模型中pg_search的代码:
include PgSearch
pg_search_scope :search, :against => [:applicant, :generic_name, :trade_name, :description],
using: {tsearch: {dictionary: "english"}},
ignoring: :accents
def self.text_search(query)
if query.present?
rank = <<-RANK
ts_rank(to_tsvector(generic_name), plainto_tsquery(#{sanitize(query)})) +
ts_rank(to_tsvector(trade_name), plainto_tsquery(#{sanitize(query)}))+
ts_rank(to_tsvector(description), plainto_tsquery(#{sanitize(query)})) +
ts_rank(to_tsvector(applicant), plainto_tsquery(#{sanitize(query)}))
RANK
where("generic_name @@ :q or trade_name @@ :q or description @@ :q or applicant @@ :q", q: query)
else
all
end
end
我的服务器输出如下:
Parameters: {"utf8"=>"✓", "query"=>"intraocular lenses"}
Parameters: {"utf8"=>"✓", "query"=>"intraocular lenses"}
Rendered layouts/_search.html.erb (1.5ms)
Rendered layouts/_search.html.erb (1.5ms)
Rendered medicaldevices/index.html.erb within layouts/application (16535.9ms)
Rendered medicaldevices/index.html.erb within layouts/application (16535.9ms)
Rendered layouts/_header.html.erb (1.8ms)
Rendered layouts/_header.html.erb (1.8ms)
Rendered layouts/_footer.html.erb (0.1ms)
Rendered layouts/_footer.html.erb (0.1ms)
Completed 200 OK in 16574ms (Views: 60.3ms | ActiveRecord: 16510.7ms)
Completed 200 OK in 16574ms (Views: 60.3ms | ActiveRecord: 16510.7ms)
这是我的索引迁移文件
class AddSearchIndexToMedicaldevices < ActiveRecord::Migration
def up
execute "create index generic_name on medicaldevices using gin(to_tsvector('english', generic_name))"
execute "create index trade_name on medicaldevices using gin(to_tsvector('english', trade_name))"
execute "create index description on medicaldevices using gin(to_tsvector('english', description))"
execute "create index applicant on medicaldevices using gin(to_tsvector('english', applicant))"
end
def down
execute "drop index generic_name"
execute "drop index trade_name"
execute "drop index description"
execute "drop index applicant"
end
end
答案 0 :(得分:2)
以下是您的回答,我认为(http://www.postgresql.org/docs/8.3/static/textsearch-tables.html)
12.2.2。创建索引
我们可以创建一个GIN索引(第12.9节)来加速文本搜索:
CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector('english', body));
请注意,使用了to_tsvector的2参数版本。只能在表达式索引中使用指定配置名称的文本搜索功能(第11.7节)。这是因为索引内容必须不受default_text_search_config的影响。如果它们受到影响,索引内容可能会不一致,因为不同的条目可能包含使用不同文本搜索配置创建的tsvector,并且无法猜测哪个是哪个。正确地转储和恢复这样的索引是不可能的。
由于在上面的索引中使用了to_tsvector的双参数版本,因此只有使用具有相同配置名称的2参数版本的to_tsvector的查询引用才会使用该索引。 即WHERE to_tsvector('english',body)@@'a&amp; b'可以使用索引,但是WHERE to_tsvector(body)@@'a&amp; b'不能。这可确保索引仅用于创建索引条目的相同配置。
答案 1 :(得分:1)
塞尔吉奥, 我按照你提到的方式进行了操作。 我不得不将上面的旧代码更改为以下内容:
where("to_tsvector('english', generic_name) @@ plainto_tsquery(:q) or
to_tsvector('english', trade_name) @@ plainto_tsquery(:q) or
to_tsvector('english', description) @@ plainto_tsquery(:q) or
to_tsvector('english', applicant)@@ plainto_tsquery(:q)", q: query).order("#{rank} DESC")
我必须添加planto_tsquery(q)来搜索多字搜索。 谢谢!