2013-02-06 60 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日志记录),以查看代码正在执行的操作。