【问题标题】:Sunspot Multi Faceted Search太阳黑子多面搜索
【发布时间】:2015-12-20 22:44:39
【问题描述】:

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

Contents
  content_name
  searchable_fields

Facets
  facet_name

ContentFacets
  content_id
  facet_id

虽然内容有_许多方面,但内容方面。我已经设法设置好一切,让它作为一个单面搜索工作——作为 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 参数来自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>

所以我的问题是:考虑到一切,我将其变成实际的多方面搜索的最佳方式是什么,而不是只使用一个方面并在每次选择新方面时都覆盖它?

【问题讨论】:

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


    【解决方案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
    

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

    所以现在在 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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 2015-01-23
      • 2014-05-30
      • 1970-01-01
      相关资源
      最近更新 更多