2012-06-06 55 views
1

我正在嘗試使用寶石輪胎在我的應用程序中進行搜索。我有表區域,城市,酒店,房間和房間信息。用寶石進行高級搜索Tire和elasticsearch

我需要的是通過查詢和其他文本字段以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 %> 

在hotel.rb

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

Elasticsearch首先是一個搜索引擎。它對錶連接的機制極其糟糕。要達到您想要的目標,您必須將數據庫解除規範化爲最多兩個表格(區域,城市,酒店) - >酒店和(房間和房間信息) - >房間,然後使用Has Child查詢(http: //www.elasticsearch.org/guide/reference/query-dsl/has-child-query.html)。不過,我認爲你可以通過切換到關係數據庫來更好。 – imotov

回答

4

在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 

不過,在這種情況下,最好將rooms_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 

希望這有助於:)