2015-05-04 4 views
1

Im начал использовать Elasticsearh в моем проекте и имел проблемы с упорядочением результатов.Заказ elasticsearch results, elasticsearch-rails gem, Rails

На самом деле мне нужно сортировать свои записи по записи 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:

  • : Код: строка

Модельная страна

  • : title_translations: hstore

Модель Регион

  • : title_translations: hstore

Модель Город

  • : title_translations: hstore

Модель PropertyObjectDescription

  • : title_translations: hstore
  • : main_text_translations: hstore

Модель PropertyObjectParameterPack

  • : Цена: hstore (пример: {мин => 10, макс => 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, чтобы получить результат, уже отсортированный, но потратить много часов, пытаясь реализовать это и потерпеть неудачу.

Что вы можете мне предложить?

UPDATE Если бы попробовать этот код:

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 по

  • по: цене
  • по: price.min
  • по: цена [: m в]
  • по: property_object_parameter_pack.price.min
  • по: property_object_parameter_pack.price [: мин]

и не повезло с упорядочением.

ответ

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 помогает с автозаполнением).

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 
+0

Hi. Спасибо за ответ. Ваш код не работает в этом представлении, с некоторым рефакторингом он выглядит так: 'query = params [: q] property_objects = запрос PropertyObject.search, options do | f | f.query {строка запроса} f.sort {по: цене, 'по возрастанию'} конец @property_objects = property_objects.records' Но это еще не сортировки. Также я попробовал [link] (http://stackoverflow.com/questions/14756149/how-to-sort-with-elasticsearch) этот пример - но то же самое - не сортировка. Думайте, что проблема в **: цена ** парам мы отправляем. Начинаем думать, что нам нужно что-то еще здесь –

+0

Извините за мой ответ ... Пожалуйста, проверьте эту ссылку для получения информации. http://www.elastic.co/guide/en/elasticsearch/guide/master/nested-sorting.html ... Думаю, вам нужно использовать nested_filter. Я не уверен, поддерживает ли elasticsearch rails файл nested_filter или нет.Вы можете попытаться построить json-запрос в таком шаблоне и отправить его в elasticsearch. –

+0

Спасибо за ссылку. Попробуем использовать этот фильтр. –

Смежные вопросы