[英]pg_search: ordering of "multisearchable" results
I'm using Rails 4.2.4 with pg_search 1.0.5.我将 Rails 4.2.4 与 pg_search 1.0.5 一起使用。
class Advert < ActiveRecord::Base
include PgSearch
multisearchable :against => [:title, :body]
end
I would like to order the pg_search results by the :created_at
date of my Advert records.我想按我的广告记录的
:created_at
日期对 pg_search 结果进行排序。 Logically, it seems to me like the following could work ( :asc
):从逻辑上讲,在我看来,以下内容可以工作(
: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">]>
But then the opposite order ( :desc
) produces the same results:但是相反的顺序 (
: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">]>
Could anybody explain how I can order my search results by the :created_at
date?有人可以解释我如何按
:created_at
日期对搜索结果进行排序吗?
UPDATE 1 : Is it possible that the order of the results is fixed by pg_search
and there isn't any way to order by 'created_at`?更新 1 :结果的顺序是否可能由
pg_search
固定并且没有任何方法可以通过“created_at”进行排序?
I am reading the documentation more carefully now and found this statement: " By default, pg_search ranks results based on the :tsearch similarity between the searchable text and the query. To use a different ranking algorithm, you can pass a :ranked_by option to pg_search_scope. " (see https://github.com/Casecommons/pg_search )我现在正在更仔细地阅读文档并发现以下语句:“默认情况下,pg_search 根据可搜索文本和查询之间的 :tsearch 相似度对结果进行排名。要使用不同的排名算法,您可以将 :ranked_by 选项传递给 pg_search_scope . ”(见https://github.com/Casecommons/pg_search )
There is a simple answer but it does not work with "multisearchable".有一个简单的答案,但它不适用于“multisearchable”。
First, I needed to change from "multisearchable" (which works with multiple models) to "pg_search_scope" (searches in a single model only).首先,我需要从“multisearchable”(适用于多个模型)更改为“pg_search_scope”(仅在单个模型中搜索)。
Second, I needed to use :order_within_rank
.其次,我需要使用
:order_within_rank
。 Since the results are all 100% matches of the search term, they have the same ranking according to pg_search
.由于结果都是搜索词的 100% 匹配,因此它们根据
pg_search
具有相同的排名。 :order_within_rank
gives a secondary rank as a tiebreaker. :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
I might be 5 years late to the party, but just stumbled upon same problem and figured out how you can do it.我参加聚会可能会迟到 5 年,但只是偶然发现了同样的问题,并想出了如何做到这一点。
Short simple answer - convert your query, ie PgSearch.multisearch('55948189')
to an array.简短的简单答案 - 将您的查询,即
PgSearch.multisearch('55948189')
转换为数组。
My example: @results = PgSearch.multisearch(params[:main_search][:query])
While you can't group or sort @results
, you can do it with @results.to_a
.我的例子:
@results = PgSearch.multisearch(params[:main_search][:query])
虽然你不能对@results
分组或排序,但你可以用@results.to_a
。
In my case I have two models - Products
and Manufacturers
(Manufacturers produce products) and I wanted to display in my search result at first all Product results and only then all manufacturers results.就我而言,我有两个模型 -
Products
和Manufacturers
(制造商生产产品),我想首先在搜索结果中显示所有产品结果,然后再显示所有制造商结果。
First, define an array to sort by:首先,定义一个数组作为排序依据:
sorting_order = ["Manufacturer", "Product"]
then然后
@results.to_a.sort_by { |x| sorting_order.index x.searchable_type }
(Note: serachable_type
is the default column of the PgSearch::Document
generated by the gem migration) (注:
serachable_type
是gem迁移生成的PgSearch::Document
的默认列)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.