将Tire与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
答案 0 :(得分:4)
你走的是正确的道路,但正如Russ Smith建议的那样,你需要使用filter
DSL。
现在,如果您只是反复拨打filter
,则会执行联合:AND
。如果您想要返回 事件用户正在观看用户关注的表演者或,则必须使用or
过滤器。
此外,为了获得最佳性能,请使用filtered
查询,而不是顶级过滤器 - 在前一种情况下,过滤器首先运行,切割语料库并仅对此子集执行查询。
代码应如下所示:
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
有关更多示例,请参阅集成测试:
答案 1 :(得分: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