太阳黑子solr如何正确搜索多个模型?所有在线示例均失败



如何在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!

您找到的搜索多个模型的方法是正确的。然而,你搜索的意义似乎并不是你想要的。看起来你好像在说:

给我所有具有这些countrystate值的Profile记录,Match记录具有此looking_for_education

然而,您的搜索结果显示:

给我所有类型为ProfileMatch且具有所有这些countrystatelooking_for_education值的所有记录

由于ProfileMatch在其各自的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

最新更新