订购elasticsearch结果,elasticsearch-rails gem,Rails

时间:2015-05-04 12:31:47

标签: ruby-on-rails sorting elasticsearch

我开始在我的项目中使用Elasticsearh,并且在结果排序方面存在问题。

实际上我需要通过连接(belongs_to)模型中的hstore记录对记录进行排序。

更多详情:

所以,我有一个我想要搜索的模型。这个模型与另一个模型有联系,这里是代码:

class PropertyObject < ActiveRecord::Base
  belongs_to :country, :counter_cache => true
  belongs_to :region, :counter_cache => true
  belongs_to :city, :counter_cache => true
  belongs_to :property_object_type, :counter_cache => true
  belongs_to :property_object_state, :counter_cache => true

  has_one :property_object_parameter_pack, dependent: :destroy
  has_one :property_object_feature_pack, dependent: :destroy
  has_one :property_object_description, dependent: :destroy
  has_one :property_object_seo_field, dependent: :destroy
end

我想在搜索结果中包含下一个字段:

模型PropertyObject:

  • :code:string

示范国家/地区

  • :title_translations:hstore

模型区域

  • :title_translations:hstore

模范城市

  • :title_translations:hstore

模型PropertyObjectDescription

  • :title_translations:hstore
  • :main_text_translations:hstore

模型PropertyObjectParameterPack

  • :price:hstore(例如:{min =&gt; 10,max =&gt; 100})

为了完成这项工作,我创建了一个关注Searchable并将其添加到我的模型PropertyObject中。 这里是代码:

module Searchable
  extend ActiveSupport::Concern

  included do
    include Elasticsearch::Model
    include Elasticsearch::Model::Callbacks

    mapping do
      indexes :property_object_parameter_pack, type: 'nested' do
        indexes :price do
          indexes :min, type: :integer
        end
      end
    end

    # Customize the JSON serialization for Elasticsearch
    def as_indexed_json(options={})
      self.as_json(
          include: {
              country: {only: :title_translations},
              region: {only: :title_translations},
              city: {only: :title_translations},
              property_object_description: {only: [:title_translations, :main_text_translations]},
              property_object_parameter_pack: {only: [:price, :area, :rooms]}
          })
    end


  end
end

搜索正在调用的控制器部分

def search
    pagen = params[:page] || 1
    @property_objects = PropertyObject.search(params[:q]).page(pagen).records

end

所以现在寻找工作,一切似乎都很好。但我需要按最低价格对搜索结果进行排序。

我尝试过订购方法,但是没有运气。

据我所知,我需要使用Elasticsearch排序,以获得已经排序的结果 - 但是花了很多时间尝试实现它并失败。

你能建议我什么?

更新 试过这段代码:

 pagen = params[:page] || 1
      query = params[:q]
      params[:order] ||= 'asc'
      property_objects = PropertyObject.search(query) do |s|
        s.query do |q|
          q.string query
        end
        s.sort { by :property_object_parameter_pack.price.min, params[:sort]}
      end
      @property_objects = property_objects.page(pagen).records

使用不同的变体

s.sort by

  • by:price
  • by:price.min
  • by:price [:min]
  • by:property_object_parameter_pack.price.min
  • by:property_object_parameter_pack.price [:min]

订购没有运气。

2 个答案:

答案 0 :(得分:1)

最后,我决定了解Elasticsearch的工作原理,并开始阅读Elasticsearch:The Definitive Guide - 答案的基础。

首先,我建议您阅读本指南并安装Marvel 。在此之后,使用CURL变得更加清晰。实际上我用Marvel发现了我的索引结构,并且只是实现它来搜索elasticsearch-rails gem的查询。

我做的下一件事 - 我已经从hstore重建价格到单独的整数列:例如price_min和price_max。 简而言之,答案代码是:

sq = {
"query": {
 "multi_match": {
    "query":    "Prague",
    "fields":   [ "country.title_translations.en",
                  "region.title_translations.en",
                  "city.title_translations.en",
                  "property_object_description.main_text_translations.en",
                  "property_object_description.title_translations.en"
                ]
  }
},
"track_scores": true,
"sort": {
  "property_object_parameter_pack.price_min": 
  { "order": "desc",
    "missing" : "_last"
  }
}} PropertyObject.search (sq)

事实上,我确信它可以与hstore一起使用。因为我将翻译存储在hstore中并且索引正常 - 只需指向右侧字段(在此任务中Marvel帮助自动完成)。

答案 1 :(得分:0)

你试过这个吗?

def search
  options = { :page => (params[:page] || 1) }
  @property_objects = PropertyObject.search, options do |f|
                        f.query { string params[:q] }
                        f.sort { by :price, 'desc' }
                      end
  @property_objects.records
end