我正在使用带有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”的字段,其中包含突出显示,但它只有匹配的字段,所以我不知道如何与item_title一起显示关联的thumb_square(显示在 _data.source 中)并突出显示。
我不知道这是否与耐嚼的宝石或一般的弹性研究有关。
答案 0 :(得分:0)
这是我不优雅的解决方案。对不起,我没有清理任何极端的代码。
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