pg_search:排序“多可搜索”结果

时间:2015-10-02 12:57:08

标签: ruby-on-rails pg-search

我正在使用Rails 4.2.4和pg_search 1.0.5。

class Advert < ActiveRecord::Base

  include PgSearch
  multisearchable :against => [:title, :body]

end

我想在广告记录的:created_at日期订购pg_search结果。从逻辑上讲,在我看来,以下内容可以起作用(:asc):

> @pgs = PgSearch.multisearch('55948189').order(created_at: :asc)

PgSearch::Document Load (136.1ms)  SELECT "pg_search_documents".* FROM "pg_search_documents" INNER JOIN (SELECT "pg_search_documents"."id" AS pg_search_id, (ts_rank((to_tsvector('simple', coalesce("pg_search_documents"."content"::text, ''))), (to_tsquery('simple', ''' ' || '55948189' || ' ''')), 0)) AS rank FROM "pg_search_documents" WHERE (((to_tsvector('simple', coalesce("pg_search_documents"."content"::text, ''))) @@ (to_tsquery('simple', ''' ' || '55948189' || ' '''))))) AS pg_search_ce9b9dd18c5c0023f2116f ON "pg_search_documents"."id" = pg_search_ce9b9dd18c5c0023f2116f.pg_search_id  ORDER BY pg_search_ce9b9dd18c5c0023f2116f.rank DESC, "pg_search_documents"."id" ASC, "pg_search_documents"."created_at" ASC
=> #<ActiveRecord::Relation [

#<PgSearch::Document id: 3148, content: "Aleksandra | Tallinn | 55948189 Simpatichnaja i se...", searchable_id: 3148, searchable_type: "Advert", created_at: "2015-10-01 11:44:06", updated_at: "2015-10-01 11:44:30">, 
#<PgSearch::Document id: 3275, content: "Aleksandra | Tallinn | 55948189 Simpatichnaja i se...", searchable_id: 3275, searchable_type: "Advert", created_at: "2015-10-02 11:05:49", updated_at: "2015-10-02 11:28:48">]> 

但是相反的顺序(:desc)会产生相同的结果:

> @pgs = PgSearch.multisearch('55948189').order(created_at: :desc)

PgSearch::Document Load (108.4ms)  SELECT "pg_search_documents".* FROM "pg_search_documents" INNER JOIN (SELECT "pg_search_documents"."id" AS pg_search_id, (ts_rank((to_tsvector('simple', coalesce("pg_search_documents"."content"::text, ''))), (to_tsquery('simple', ''' ' || '55948189' || ' ''')), 0)) AS rank FROM "pg_search_documents" WHERE (((to_tsvector('simple', coalesce("pg_search_documents"."content"::text, ''))) @@ (to_tsquery('simple', ''' ' || '55948189' || ' '''))))) AS pg_search_ce9b9dd18c5c0023f2116f ON "pg_search_documents"."id" = pg_search_ce9b9dd18c5c0023f2116f.pg_search_id  ORDER BY pg_search_ce9b9dd18c5c0023f2116f.rank DESC, "pg_search_documents"."id" ASC, "pg_search_documents"."created_at" DESC
=> #<ActiveRecord::Relation [

#<PgSearch::Document id: 3148, content: "Aleksandra | Tallinn | 55948189 Simpatichnaja i se...", searchable_id: 3148, searchable_type: "Advert", created_at: "2015-10-01 11:44:06", updated_at: "2015-10-01 11:44:30">, 
#<PgSearch::Document id: 3275, content: "Aleksandra | Tallinn | 55948189 Simpatichnaja i se...", searchable_id: 3275, searchable_type: "Advert", created_at: "2015-10-02 11:05:49", updated_at: "2015-10-02 11:28:48">]>

有人可以解释我如何在:created_at日期之前订购我的搜索结果吗?

更新1 :结果的顺序是否可能由pg_search修正,并且没有任何方法可以通过'created_at`进行排序?

我现在正在更仔细地阅读文档,并发现这句话:“默认情况下,pg_search根据搜索文本和查询之间的:tsearch相似性对结果进行排名。要使用不同的排名算法,您可以通过a:pg_search_scope的ranking_by选项。“(参见https://github.com/Casecommons/pg_search

2 个答案:

答案 0 :(得分:5)

有一个简单的答案,但它不适用于“多可搜索”。

首先,我需要将“multisarchable”(适用于多个模型)更改为“pg_search_scope”(仅在单个模型中搜索)。

其次,我需要使用:order_within_rank。由于结果都是搜索字词的100%匹配,因此根据pg_search,它们具有相同的排名。 :order_within_rank将次要排名作为决胜局。

class Advert < ActiveRecord::Base

  include PgSearch
  pg_search_scope :search_by_full_advert, 
                  :against => [:title, :body],
                  :order_within_rank => "adverts.created_at DESC"

end

答案 1 :(得分:0)

我可能要晚5年参加聚会,但偶然发现了同样的问题,并弄清楚了如何做到这一点。

简短的简短答案-将您的查询(即PgSearch.multisearch('55948189'))转换为数组。

我的例子: @results = PgSearch.multisearch(params[:main_search][:query]) 虽然无法对@results进行分组或排序,但是可以使用@results.to_a进行。

就我而言,我有两种型号-ProductsManufacturers(制造商生产产品),我想首先在搜索结果中显示 所有产品结果只有这样所有制造商的结果。

首先,定义一个数组进行排序:

sorting_order = ["Manufacturer", "Product"]

然后

@results.to_a.sort_by { |x| sorting_order.index x.searchable_type }

(注意:serachable_type是gem迁移生成的PgSearch::Document的默认列)