NEST(ElasticSearch)匹配文档的亮点

时间:2013-07-23 08:37:09

标签: elasticsearch highlight nest

我在ElasticSearch中使用C#NEST。我可以查询产品的索引,并查看其NameCategoryName字段中的匹配项。我也可以使用Highlights扩展查询。

现在在我的IQueryResponse回复中,我有两个集合:(1).Documents和(2).Highlights

例如:考虑搜索:“cat”,它有3个文档结果:

{
   { Name: "Cat product", CategoryName: "Category1" },
   { Name: "Some product", CategoryName: "Category2" },
   { Name: "Some product2", CategoryName: "Category3" }
}

但现在我有4个高亮显示结果:

{
   { Field: "name", Highlights: ['"<u>Cat</u> product"'] },
   { Field: "categoryName", Highlights: ['"<u>Cat</u>egory1"'] },
   { Field: "categoryName", Highlights: ['"<u>Cat</u>egory2"'] },
   { Field: "categoryName", Highlights: ['"<u>Cat</u>egory3"'] }
}

他们似乎并没有相互关联。 我如何知道哪个Highlight项属于哪个Document项?

2 个答案:

答案 0 :(得分:3)

IQueryResponse还会公开.DocumentsWithMetaDataIEnumerable<IHit<T>>,其中T是您文档的类型

这基本上是结果的展开视图,因为elasticsearch IHit<T>返回有许多有用的属性,例如Highlights

我已将一个DocumentId结果添加到突出显示类Highlight中,这样无论您如何进入突出显示,都可以轻松地将其与回放相关联。

因此,现在使用.DocumentsWithMetaData,下一个版本将为高亮显示提供更合理的API。

答案 1 :(得分:0)

这是版本7.x的更新答案。与以前一样,您会收到两个集合:.Documents和.Hits。 在.Hits中,每个人都有一个.Id,该值与elasticsearch中索引的_id匹配。注意:如果您在查询中请求多个高亮显示.NumberofFragments,您将继续覆盖下面的代码中的result.title和result.content,因此以一个宽松的示例来说明如何将高亮显示结果与正确的文档结果,然后用包含突出显示的字段覆盖文档字段。

if (response.Documents.Count > 0)
{
    foreach (MyResultClass result in response.Documents) //cycle through your results
    {
         foreach (var hit in response.Hits) // cycle through your hits to look for match
         {
              if (hit.Id == result.id) //you found the hit that matches your document
              {
                    foreach (var highlightField in hit.Highlight)
                    {
                           if (highlightField.Key == "title")
                           {
                                foreach (var highlight in highlightField.Value)
                                {
                                    result.title = highlight.ToString();
                                }
                           }
                           else if (highlightField.Key == "content")
                           {
                                foreach (var highlight in highlightField.Value)
                                {
                                    result.content = highlight.ToString();
                                }
                           }
                   }
             }
      }
}