3

将轮胎与 Mongoid 一起使用,我无法弄清楚如何构造查询以使用 ElasticSearch 查找事件。特别是,我试图找到用户正在观看的事件以及用户关注的表演者的事件:

# app/models/event.rb
class Event
  include Mongoid::Document
  include Tire::Model::Search
  include Tire::Model::Callbacks

  field :name, type: String

  has_and_belongs_to_many :performers
  has_many :watchers, class_name: 'User'

  mapping do
    indexes :name
    indexes :watcher_ids, type: 'string', index: :not_analyzed
    indexes :performer_ids, type: 'string', index: :not_analyzed
  end
end

以下查询仅适用于观察者或执行者。

Tire.search 'events' do
  query do
    string params[:query]
    # Only one of these will work at a time:
    terms :performer_ids, current_user.followed_performers.collect(&:id).map(&:to_s)
    terms :watcher_ids, [current_user.id.to_s]
  end
end
  • 小编辑,因为我输入了我的示例错误。

这是一个似乎“有效”的解决方案......但感觉不对

Tire.search('events') do
  query do
    boolean do
      should { string params[:query] }
      should { string "performer_ids:#{current_user.followed_performers.collect(&:id).map(&:to_s).join(',')}" }
      should { string "watcher_ids:#{current_user.id.to_s}" }
    end
  end
end
4

2 回答 2

4

You're on a right path, but as advised by Russ Smith, you need to use a filter DSL.

Now, if you just repeatedly call filter, you'll perform a union: AND. If you want to return either events user is watching or by performers the user follows, you have to use a or filter.

Also, for best performance, use the filtered query, as opposed to the top level filter -- in the former case, filters run first, slicing your corpus and perform queries only on this subset.

The code should look like this:

Tire.search 'events' do
  query do
    filtered do
      query do
        string params[:query]
      end
      filter :or, terms: { organization_ids: current_user.followed_performers.collect(&:id).map(&:to_s) },
                  terms: { watcher_ids:      [current_user.id.to_s] }
    end
  end
end

See the integration tests for more examples:

于 2012-12-22T09:52:48.430 回答
2

我认为您正在寻找的是过滤器。这不是经过全面测试的代码,但它可能会引导您朝着正确的方向前进。

class Event
  include Mongoid::Document
  include Tire::Model::Search
  include Tire::Model::Callbacks

  field :name, type: String

  has_and_belongs_to_many :performers
  has_many :watchers, class_name: 'User'

  mapping do
    indexes :name
    indexes :watcher_ids, type: 'integer', index: :not_analyzed
    indexes :performer_ids, type: 'integer', index: :not_analyzed
  end
end

Tire.search('events') do
  query do
    string 'my event'
  end

  filter :in, :organization_ids, [1,2,3]
  filter :in, :watcher_ids, [1]
end
于 2012-12-22T01:04:04.060 回答