如何在SunSpot Solr中正确搜索多个模型?
配置文件模型
has_one :match
searchable do
string :country
string :state
string :city
end
匹配模型
belongs_to :profile
searchable do
string :looking_for_education
integer :age_from
integer :age_to
end
配置文件控制器#索引
def index
@search = Sunspot.search Profile, Match do
with(:country, params[:country])
with(:state, params[:state])
with(:looking_for_education, params[:looking_for_education]) <= from the 2nd model
end
@profiles = @search.results
end
此操作失败:
Using a with statement like
with(:age).between(params[:age_from]..params[:age_to])
undefined method `gsub' for nil:NilClass
删除
带有(:age).介于(params[:age_from]..params[;age_to])行之间,然后尝试
然后它尝试加载
view app/views/educators/educator.html.haml
不存在(im仅使用
/app/views/profiles/_profile.html.haml
显示配置文件
编辑#1:
在ruby on rails中,哪些优秀的开源项目以更高级的方式使用了spoop和solr?也许我能在那里找到答案。这个方向上的任何答案也将被接受,如果它产生了这个问题,thx!
您找到的搜索多个模型的方法是正确的。然而,你搜索的意义似乎并不是你想要的。看起来你好像在说:
给我所有具有这些
country
和state
值的Profile
记录,和其Match
记录具有此looking_for_education
值
然而,您的搜索结果显示:
给我所有类型为
Profile
或Match
且具有所有这些country
、state
和looking_for_education
值的所有记录
由于Profile
和Match
在其各自的searchable
块中都没有所有这些字段,因此没有任何一条记录能够匹配您指定的条件。
如果我对你上面的预期行为是正确的,那么你需要在配置文件的searchable
块中包括配置文件的相关匹配信息,就像这样:
class Profile < ActiveRecord::Base
has_one :match
searchable do
string(:country)
string(:state)
string(:city)
string(:looking_for_education) { match.looking_for_education }
integer(:age_from) { match.age_from }
integer(:age_to) { match.age_to }
end
end
在这里,我们已经告诉Sunspot对配置文件的匹配关联的属性进行索引,就好像它们生活在配置文件本身上一样。在相应的块中,我们已经告诉Sunspot如何在配置文件被索引时填充这些值。
这将允许您只使用Profile
型号编写搜索:
def index
@search = Sunspot.search Profile do
with(:country, params[:country])
with(:state, params[:state])
with(:looking_for_education, params[:looking_for_education])
with(:age).between(params[:age_from]..params[:age_to])
end
@profiles = @search.results
end
此搜索将只返回Profile
记录,同时仍然反映每个配置文件的匹配关联的属性,因为我们在对配置文件进行索引时存储了这些记录。
请注意,在为模型编制索引时,这会增加复杂性。如果Match
记录发生更改,则现在需要对其关联的配置文件进行重新索引,以反映这些更改。
当我必须搜索多个型号时,这就是我要做的
Sunspot.search [Model1, Model2] do
....
end
@moises zaragoza正确回答了您的问题,但您在想做什么方面遇到的问题比您想象的要多。
第一个错误:
Using a with statement like
with(:age).between(params[:age_from]..params[:age_to])
undefined method `gsub' for nil:NilClass
很可能是因为params[:age_from]和/或params[;age_to]为零而产生的。我不能保证,因为你还没有展示堆叠比赛。只有当过滤器存在时,才能通过过滤器进行修复:带(:age).介于(params[:age_from]..params[:age_to])如果params[;age_from]存在?和params[:age_to]。现在?
第二个错误
与您的观点相关。我假设您正在使用rails helper部分对象助手之一渲染集合或对象,而不指定部分对象(同样,如果没有代码,这比其他任何事情都更适合猜测):
<%= render @results %>
或
<% @results.each do |result| %>
<%= render result %>
<% end %>
当Rails没有指定分部时,它会根据对象类型猜测分部名称。在这种情况下,如果您的对象是Educator类,它可能是Profile的一个子类,Rails将查找分部'Educator/_Educator.html.erb。确保根据对象类型呈现正确的分部,这将确保您呈现所需的内容。
这里是使用with
在匹配字符串上搜索不同模型的答案
searchable(:auto_index => AppConfig.solr.auto_index) do
string :category_name, :stored => true
text :content, :stored => true
text :title
string :company_id, :stored => true
time :published_on
end
search do |q|
if params[:keyword].present?
q.fulltext params[:keyword] do
fields(:deal_data)
end
end
if (ids = params["company_id"]).present?
ids = ids.split(",")
q.with(:company_id,ids) #here company id formate should be ["***","***"]
end
end