2013-02-06 98 views
0

我在使用彈性搜索和輪胎時沒有返回任何結果。我正在使用Ruby 1.9.3和Rails 3.2.11。通過參數查詢彈性搜索對象關聯

在我的控制器我打電話:

@location_id = 1 
@listings = Listing.search(params.merge!(location_id: @location_id)) 

在我的房源模型我有

mapping do 
    indexes :id, type: 'integer' 
    ... 
    indexes :author do 
     indexes :location_id,  :type => 'integer', :index => :not_analyzed 
     ... 
end 

def self.search(params={}) 
     tire.search(load: true, page: params[:page], per_page: 20) do |search| 

     search.query { string params[:query], :default_operator => "AND" } if params[:query].present? 
     search.filter :range, posted_at: {lte: DateTime.now} 

     search.filter :term, "author.location_id"  => params[:location_id] 
end 

我有300個結果,所有有1 LOCATION_ID數據庫這樣我就可以」 t似乎找出爲什麼它返回一個零集?如果我註釋掉author.location_id搜索過濾器行,它會按預期返回所有其他結果?

回答

1

有幾件事需要在像你這樣的情況下加以解決。讓我們先從一個完全工作代碼:

require 'active_record' 
require 'tire' 
require 'logger' 

# Tire.configure { logger STDERR } 
# ActiveRecord::Base.logger = Logger.new(STDERR) 

Tire.index('articles').delete 

ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ":memory:") 
ActiveRecord::Schema.define(version: 1) do 
    create_table :articles do |t| 
    t.string :title 
    t.integer :author_id 
    t.date :posted_at 
    t.timestamps 
    end 
    create_table :authors do |t| 
    t.string :name 
    t.integer :number, :location_id 
    t.timestamps 
    end 
    add_index(:articles, :author_id) 
    add_index(:authors, :location_id) 
end 

class Article < ActiveRecord::Base 
    belongs_to :author, touch: true 
    self.include_root_in_json = false 

    include Tire::Model::Search 
    include Tire::Model::Callbacks 

    mapping do 
    indexes :title 

    indexes :author do 
     indexes :location_id, type: 'integer' 
    end 
    end 

    def self.search(params={}) 
    tire.search load: {include: 'author'} do |search| 
     search.query do |query| 
     query.filtered do |f| 
      f.query { params[:query].present? ? match([:title], params[:query], operator: 'and') : match_all } 
      f.filter :range, 'posted_at' => { lte: DateTime.now } 
      f.filter :term, 'author.location_id' => params[:location_id] 
     end 
     end 
    end 
    end 

    def to_indexed_json 
    to_json(only: ['title', 'posted_at'], include: { author: { only: [:location_id] } }) 
    end 
end 

class Author < ActiveRecord::Base 
    has_many :articles 

    after_touch do 
    articles.each { |a| a.tire.update_index } 
    end 
end 

# ----- 

Author.create id: 1, name: 'John', location_id: 1 
Author.create id: 2, name: 'Mary', location_id: 1 
Author.create id: 3, name: 'Abby', location_id: 2 

Article.create title: 'Test A', author: Author.find(1), posted_at: 2.days.ago 
Article.create title: 'Test B', author: Author.find(2), posted_at: 1.day.ago 
Article.create title: 'Test C', author: Author.find(3), posted_at: 1.day.ago 
Article.create title: 'Test D', author: Author.find(3), posted_at: 1.day.from_now 

Article.index.refresh 

# ----- 

articles = Article.search query: 'test', location_id: 1 
puts "", "Documents with location:1", '-'*80 
articles.results.each { |a| puts "* TITLE: #{a.title}, LOCATION: #{a.author.location_id}, DATE: #{a.posted_at}" } 

articles = Article.search query: 'test', location_id: 2 
puts "", "Documents with location:2", '-'*80 
articles.results.each { |a| puts "* TITLE: #{a.title}, LOCATION: #{a.author.location_id}, DATE: #{a.posted_at}" } 
puts "(NOTE: 'D' is missing, because is not yet posted)" 

articles = Article.search query: 'test b', location_id: 1 
puts "", "Documents with query:B and location:1", '-'*80 
articles.results.each { |a| puts "* TITLE: #{a.title}, LOCATION: #{a.author.location_id}, DATE: #{a.posted_at}" } 

首先,它通常是創建一個孤立的,提取的情況下,像這樣的好主意。

在你的示例代碼中,我假設你有一個關係Listing belongs_to :author。你需要正確地定義映射和序列化,我再次假設你做了。

至於查詢本身:

  • 除非你使用面導航,使用filtered查詢,而不是最高級別的過濾器,在我的示例代碼。

  • 不要使用string查詢,除非您真的想將Lucene查詢字符串查詢的所有功能(和易碎性!)公開給用戶。

  • 使用match查詢,爲你的「通用目的」查詢 - 輪胎灑在它上面的一些糖,從而輕鬆地創建multi_match查詢等

  • 在您的示例中的過濾器語法正確。當filter方法在輪胎中被多次調用時,它創建和and過濾器。

取消註釋輪胎日誌配置(也可能是ActiveRecord日誌記錄),以查看代碼正在執行的操作。