【问题标题】:Can't get highlighting on search results for relations using chewy gem无法在使用耐嚼宝石的关系搜索结果中突出显示
【发布时间】:2015-01-28 21:41:38
【问题描述】:

我将耐嚼的 gem 用于带有 Rails 的 elasticSearch。我有相关文档,我想在结果中同时显示带有突出显示的字段和其他一些字段。

当我返回搜索结果时,突出显示“主”记录中的匹配项,而不是“相关记录”中的匹配项(不确定正确的术语是什么)。

我的 search_index.rb 看起来像这样:

define_type PlayList.includes(:play_list_items,:user) do
  field :title
  field :description
  field :thumb_missing, value: ->{intro_image_file_name.nil?}
  field :thumb_square, value: ->{intro_image(:thumb_square)}
  field :play_list_items do
    field :item_title, value: ->{title}
    field :commentary_text
    field :thumb_square, value: ->{get_image(:thumb_square)}
  end
  field :user do
    field :name
    field :avatar, value: ->{avatar(:tiny)}
  end
end

查询看起来像这样

  @play_lists =  SearchIndex::PlayList.query(multi_match: {
    query: params[:term], 
    fields: ["title","description","item_title","commentary_text"]
 }).highlight(
pre_tags:["<mark>"],
 post_tags:["</mark>"],
 fields: {
     title:{},
     description:{},
     item_title:{},
     commentary_text:{}
     })

当我在标题上找到匹配项时,title 方法会返回标题文本并突出显示该术语。但是,我总是将 play_List_items 作为没有突出显示的哈希数组返回。

当我使用“to_a”进行序列化时,我看到在 _data 中有一个名为“highlight”的字段的哈希,其中包含突出显示,但它只有匹配的字段,所以我不知道如何将关联的 thumb_square(出现在 _data.source 中)与 item_title 一起突出显示。

我不知道这是否与耐嚼的 gem 或一般的弹性搜索有关。

【问题讨论】:

  • 您好,您找到问题的答案了吗?顺便问一下,你知道如何对字段进行加权吗?
  • 我没有找到一个优雅的解决方案。我最终不得不取出突出显示的项目并删除突出显示以将它们与 play_list_items 哈希匹配。

标签: ruby-on-rails elasticsearch highlighting chewy-gem


【解决方案1】:

这是我的非优雅解决方案。抱歉,我没有清理任何冗长的代码。

class SearchController < ApplicationController

  def index
  play_lists =  SearchIndex::PlayList.query(multi_match: {
    query: params[:term], 
    fields: ["title","description","item_title","commentary_text","name","user_id"]
    }).filter(term:{public:true}).highlight(
        pre_tags:["<mark>"],
        post_tags:["</mark>"],
        fields: {
          title:{},
          description:{},
          item_title:{},
          commentary_text:{},
          name:{}
          }
        ).to_a

     # search results include mark for title and description but not for item_title or commentary_text
     # if any item leve matches, find associated items and show with highlights from _data  
     @play_lists=play_lists.map do |play_list|
       match_indexes=Set.new
       highlight= play_list._data["highlight"]
       if (highlight["item_title"])
         highlight["item_title"].each do |hl_title|
           nhl_title=hl_title.gsub("<mark>","").gsub("</mark>","")  #remove the highlighting so we can do comparisons.
           play_list.play_list_items.each_with_index do |pli, ndx|
             if (pli["item_title"]==nhl_title)  # if match without highlight copy in highlight
               pli["item_title"]=hl_title
               match_indexes.add(ndx)
             elsif pli["item_title"].to_s.include? nhl_title
               pli["item_title"]="..."+hl_title+"..."
               match_indexes.add(ndx)
             end
           end
         end
       end
       if (highlight["commentary_text"])
         highlight["commentary_text"].each do |hl_ct|
           nhl_ct=hl_ct.gsub("<mark>","").gsub("</mark>","")  #remove the highlighting so we can do comparisons.
           play_list.play_list_items.each_with_index do |pli, ndx|
             if pli["commentary_text"]==nhl_ct  # if match without highlight copy in highlight
               pli["commentary_text"]=hl_ct
               match_indexes.add(ndx)
            elsif pli["commentary_text"].to_s.include? nhl_ct
              pli["commentary_text"]="..."+hl_ct+"..."
              match_indexes.add(ndx)
             end
           end
         end
       end
       if match_indexes.empty?
         items_to_show=play_list.play_list_items.slice(0,3)  # we will only show fist 3 if no matches 
       else
         items_to_show=[]
         match_indexes.each do |mi|
           items_to_show.push (play_list.play_list_items[mi])
         end
       end
       pl=play_list.attributes
       pl["play_list_items"]=items_to_show
       pl["user"]["name"] = highlight["name"][0] if (highlight["name"])
       if pl["title"].is_a? Array
         pl["title"]="..."+pl["title"].join("...")+"..."
       end
       pl["description"] ||=""
       if pl["description"].is_a? Array
         pl["description"]="..."+pl["description"].join("...")+"..."
       end
       pl           
     end
end

【讨论】:

  • 我不接受我自己的解决方案,因为如果有人向我展示更好的解决方案,我会非常高兴。我认为这确实是一种解决方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2014-03-07
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-25
相关资源
最近更新 更多