PG搜索没有首先返回完全匹配 - Rails 4

时间:2015-12-04 04:13:03

标签: ruby-on-rails ruby postgresql ruby-on-rails-4 full-text-search

我在我的Rails 4应用程序上使用PgSearch。在返回搜索结果时,一直试图弄清楚如何提升完全匹配。

目前,如果用户搜索"焦炭" ..."焦炭零"将首先显示...然后是"焦炭"。我想"可乐"成为第一。

这是我的代码:

include PgSearch
pg_search_scope :search, :against => { :specific => 'A', :title => 'B', :aka => 'C'},
                         :using => { dmetaphone: {}, tsearch: { dictionary: 'english' }, 
                                     trigram: {:threshold => 0.3} },
                         ignoring: :accents

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

您可以尝试按pg_search_rank排序:

@beverages = Beverage.search("Coke").with_pg_search_rank
@beverages = @beverages.sort_by {|b| b.pg_search_rank}

答案 1 :(得分:0)

所以,我最终忽略了我的默认范围 - 按updated_at排序。删除后,它完美地工作了......

答案 2 :(得分:0)

您也可以尝试“标准化:2”:https://github.com/Casecommons/pg_search#normalization

(仅在此处发布一些其他人遇到与我相同的问题,但不是由updated_at默认情况下订购引起的)

一个例子:

  pg_search_scope :search_by_name,
                  against: :name,
                  using: { tsearch: { prefix: true }}

[22] pry(main)> Category.search_by_name('Los Angeles').pluck(:name)
   (3.7ms)  SELECT "categories"."name" FROM "categories" INNER JOIN (SELECT "categories"."id" AS pg_search_id, (ts_rank((to_tsvector('simple', coalesce("categories"."name"::text, ''))), (to_tsquery('simple', ''' ' || 'Los' || ' ''' || ':*') && to_tsquery('simple', ''' ' || 'Angeles' || ' ''' || ':*')), 0)) AS rank FROM "categories" WHERE (((to_tsvector('simple', coalesce("categories"."name"::text, ''))) @@ (to_tsquery('simple', ''' ' || 'Los' || ' ''' || ':*') && to_tsquery('simple', ''' ' || 'Angeles' || ' ''' || ':*'))))) AS pg_search_a6216ea03e578f212dd604 ON "categories"."id" = pg_search_a6216ea03e578f212dd604.pg_search_id ORDER BY pg_search_a6216ea03e578f212dd604.rank DESC, "categories"."id" ASC
=> ["Los Angeles Angels",
 "Los Angeles Lakers",
 "Los Angeles angels",
 "Los Angeles Dodgers",
 "Los Angeles Rams",
 "Los Angeles",
 "Los Angeles Clippers"]

——

  include PgSearch
  pg_search_scope :search_by_name,
                  against: :name,
                  using: { tsearch: { prefix: true, normalization: 2 }}

[20] pry(main)> Category.search_by_name('Los Angeles').pluck(:name)
   (3.4ms)  SELECT "categories"."name" FROM "categories" INNER JOIN (SELECT "categories"."id" AS pg_search_id, (ts_rank((to_tsvector('simple', coalesce("categories"."name"::text, ''))), (to_tsquery('simple', ''' ' || 'Los' || ' ''' || ':*') && to_tsquery('simple', ''' ' || 'Angeles' || ' ''' || ':*')), 2)) AS rank FROM "categories" WHERE (((to_tsvector('simple', coalesce("categories"."name"::text, ''))) @@ (to_tsquery('simple', ''' ' || 'Los' || ' ''' || ':*') && to_tsquery('simple', ''' ' || 'Angeles' || ' ''' || ':*'))))) AS pg_search_a6216ea03e578f212dd604 ON "categories"."id" = pg_search_a6216ea03e578f212dd604.pg_search_id ORDER BY pg_search_a6216ea03e578f212dd604.rank DESC, "categories"."id" ASC
=> ["Los Angeles",
 "Los Angeles Angels",
 "Los Angeles Lakers",
 "Los Angeles angels",
 "Los Angeles Dodgers",
 "Los Angeles Rams",
 "Los Angeles Clippers"]