太阳黑子多面搜索

时间:2015-09-23 14:37:51

标签: ruby-on-rails sunspot faceted-search

我正在构建一个使用Sunspot作为后端搜索引擎并实现分面搜索的API。对于我如何为所有内容执行许多不同的方面类型,我有以下模型:

Contents
  content_name
  searchable_fields

Facets
  facet_name

ContentFacets
  content_id
  facet_id

Content has_many facets虽然是content_facets。我已经设法完成所有设置以使其作为单个分面搜索工作 - 作为API返回它需要的所有内容,当前端应用程序发送回必要的参数时,它将向下钻取该一个方面,但是,我不能让它从那里做多个方面。这是我所做的搜索(再次,这是有效的):

#SearchController

facet_id = Facet.find_by_name(params[:commit]).id

@search = Content.search do
    fulltext params[:search]
    with(:facet_ids, facet_id) if params[:commit].present?
    facet(:facet_ids)
    paginate :page => 1, :per_page => 300
end

facets = @search.facet(:facet_ids).rows.map { |row| row.instance.name }

render :json => [facets, @search.results]

然后是内容模型,了解它的配置方式:

searchable do
  text :searchable_fields
  integer :facet_ids, :multiple => true, :references => Facet
end

最后,这是在查询我的API的前端应用程序上处理它的方式:(看起来好像以前的参数作为路由本身的参数传回,而来自:commit param来自submit_tag是确定特定方面名称的原因)

<% if @facets %>
  <div id="facets">
  <h3>Given - <%= @search_params %></h3>
  <ul>
    <% @facets.each do |facet| %>
      <%= form_tag facet_path(@search_params), method: "POST" do %>
        <li><%= submit_tag facet %></li>
      <% end %>
    <% end %>
  </ul>
</div>
  

所以我的问题是:给出一切最好的方法让我把它变成一个实际的多面搜索,而不是仅仅使用一个方面并在每次选择一个新方面时覆盖它?

1 个答案:

答案 0 :(得分:1)

针对您的特定问题,以下方法应该有效 -

在您的视图中,只需在submit_tag行

上方添加此行即可
<li><%= hidden_field_tag :existing_facets, @existing_facets %></li>

然后,在您调用API之前,有一大堆代码,如下所示:

@existing_facets = ""

        unless facet_params[:existing_facets].nil?
            @existing_facets =  "#{facet_params[:existing_facets]}+#{facet_params[:commit]}"
        end

这将跟踪用户为特定查询选择的所有方面,同时仍保留原始搜索参数 - 这些按顺序存储在字符串中以便于使用,由a +标志。

现在,在API方面,我会将您的搜索代码更改为以下内容:

facets = gather_facets(params[:existing_facets], params[:commit])

@search = Content.search do
    fulltext params[:search]
    facets.each do |facet|
        facet_id = Facet.find_by_name(facet).id
        with(:facet_ids, facet_id)
    end
    facet(:facet_ids)
    paginate :page => 1, :per_page => 300
end

facets = @search.facet(:facet_ids).rows.map { |row| row.instance.name }

render :json => [facets, @search.results]

def gather_facets(existing_str, new_facet)
  arr = existing_str.scan(/([^+]+)/).flatten << new_facet
end

这将跟踪所有选定的方面,按顺序查询它们,并在搜索查询中迭代问题导致API减速之前缩小自身范围(假设方面正确完成:P)