我在使用 Sunspot 时按组搜索时遇到一些问题。
这是一个例子:
# == Schema Information
#
# Table name: movies
#
# id :integer(4) not null, primary key
# title :string(255)
class Movie < ActiveRecord::Base
has_and_belongs_to_many :actors
searchable do
text :title
integer :ages, multiple: true do
actors.map(&:age)
end
text :names, multiple: true do
actors.map(&:name)
end
end
end
# == Schema Information
#
# Table name: actors
#
# id :integer(4) not null, primary key
# name :string(255)
# age :integer(30)
class Actor < ActiveRecord::Base
has_and_belongs_to_many :movies
searchable do
integer :age
text :name
end
end
我想找到每部有 30 岁 Actor 名为 John 的电影。
Movie.search do
with(:names).equal_to("John")
with(:ages).equal_to(30)
with(:title).equal_to("...")
# ...
end
问题在于它可能会找到一部有两个 Actor 的电影;一位名叫约翰,一位年龄为 30 岁。有没有办法以某种方式将其组合在一起,以便电影中找到一位名叫约翰的 Actor ,年龄为 30 岁?
最佳答案
解决方案,就像 Maurício Linhares 在他的评论中所写的那样,是遍历 Actor 模型并按电影分组。
问题是 Sunspot 不支持 Solr 3.3 或 4.0,这是唯一支持分组的 Solr 版本。
这是我使用 Sunspot 1.2.1 和 Solr 3.3 的解决方案。
在我的示例中,movie_id
放置在 actor 表中,这在我的实际应用程序中并未完成。
# == Schema Information
#
# Table name: actors
#
# id :integer(4) not null, primary key
# name :string(255)
# created_at :datetime
# updated_at :datetime
# movie_id :integer(4)
#
class Actor < ActiveRecord::Base
searchable do
# We need to store the movie_id as an string
# So it can be sorted. We also need to pass the
# stored: true params
string :movie_id, stored: true do
movie_id.to_s
end
end
def search_using_solr
scoped = Sunspot.new_search(Actor)
scoped.build do
adjust_solr_params do |params|
params[:group] = true
params[:"group.field"] = "movie_id_s"
params[:"group.format"] = "simple"
end
end
# Sunspot 1.2.1 doesn't support grouping, so we need to do some hacking.
def scoped.hits
@hits ||= @solr_result["grouped"].values.first["doclist"]["docs"].map do |doc|
Sunspot::Search::Hit.new(doc, nil, self)
end
end
def scoped.total
@total ||= @solr_result["grouped"]["movie_id_s"]["matches"] || 0
end
# Here we'll only fetch the stored data from Solr it self,
# and then pass it manualy to ActiveRecord.
Movie.where({
id: scoped.execute.hits.map{ |h| h.stored(:movie_id) }
})
end
end
alindeman 的 example gist 值得信赖。
关于ruby-on-rails - 使用 Sunspot/Solr 进行组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7031836/