Расширенный поиск с помощью gem Tire и elasticsearch

Я пытаюсь использовать драгоценные камни для поиска в своем приложении. У меня есть таблицы Areas, Cities, Hotels, Rooms и RoomInformations.

Мне нужно найти отель по запросу и другим текстовым полям, таким как date_from, date_to и количество комнат. В модели у меня есть метод, который вычисляет, есть ли в отеле свободные номера, и отправляет логическое значение. Как я могу использовать этот логический метод для фильтрации запроса?

Спасибо

в hotel.html.erb

<%= form_tag search_hotels_path, :method => 'post' do %>
  <%= label_tag :query %>
  <%= text_field_tag :query, params[:query] %>
  <%= label_tag 'From' %>
  <%= text_field_tag :date_f, params[:date_from] %>
  <%= label_tag 'To' %>
  <%= text_field_tag :date_to, params[:date_to] %>
  <%= label_tag 'Rooms' %>
  <%= text_field_tag :rooms, params[:rooms] %>
  <%= submit_tag :search %>
<% end %>

в гостинице.рб

class Hotel < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks

belongs_to :city
belongs_to :area
has_one :area, :through => :city
has_many :rooms, :dependent => :delete_all


def search(params)

        tire.search do
            query do
                boolean do  
                    must { string params[:query] } if params[:query].present?
                    must { term rooms_available params, true}
                end
            end 
        end

end

self.include_root_in_json = false
def to_indexed_json
    to_json(methods: [:area_name,:city_name])
end

def area_name
    city.area.name
end
def city_name
    city.name
end


def rooms_available params
    exit
    begin_date = params[:date_from].to_date
    end_date = params[:date_to].to_date
    number_of_rooms = params[:rooms]

    rooms.each do |room|
        if room.available(begin_date, end_date, number_of_rooms)
            return true
        end
    end
    return false
end

end

person Jiří Kratochvíl    schedule 06.06.2012    source источник
comment
Elasticsearch — это прежде всего поисковая система. Он имеет чрезвычайно плохой механизм для соединения таблиц. Чтобы достичь того, чего вы хотите, вам придется денормализировать базу данных не более чем на две таблицы: (Areas, Cities, Hotels) -> Hotels и (Rooms и RoomInformations) -> Rooms, а затем использовать запрос Has Child (elasticsearch.org/guide/reference/query-dsl/). Однако я думаю, что вам может быть лучше переключиться на реляционную базу данных.   -  person imotov    schedule 06.06.2012


Ответы (1)


Поместите это в метод to_json:

def to_json
  {
    :area_name => self.area_name, 
    :city_name => self.city_name,
    :rooms_available => self.rooms_available
   }.to_json
end

Затем:

def search(params)

    tire.search do
        query do
            boolean do  
                must { string params[:query] } if params[:query].present?
                must { term rooms_available, true}
            end
        end 
    end

end

В этом случае, однако, лучше поместить room_available в фильтр, так как это обязательно, и вы не заботитесь о подсчете очков по этому пункту.

def search(params)

    tire.search do
        query do
            boolean do  
                must { string params[:query] } if params[:query].present?
            end
        end 
        filter do
            boolean do  
               must { term rooms_available, true}
            end
        end
    end

end

Надеюсь это поможет :)

person farid    schedule 22.06.2012