问题
I'm using C# NEST with ElasticSearch. I'm able to query an index of Products and look in their Name
and CategoryName
fields for matches. I can also extend the query using Highlights
.
Now in my IQueryResponse
response I have two collections: (1) .Documents
and (2) .Highlights
.
e.g.: Consider the search for: "cat" which has 3 document results:
{ { Name: "Cat product", CategoryName: "Category1" }, { Name: "Some product", CategoryName: "Category2" }, { Name: "Some product2", CategoryName: "Category3" } }
But now I have 4 highlight results:
{ { 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"'] } }
They seem to be in no way related to each other. How do I know which Highlight
item belongs to which Document
item?
回答1:
IQueryResponse
also exposes .DocumentsWithMetaData
of type IEnumerable<IHit<T>>
where T is the type of your document
This is basically the unwrapped view of the results as return by elasticsearch IHit<T>
has many useful properties such as the Highlights
.
I've added a DocumentId result to the highlight class Highlight
so that no matter how you get to the highlight you can relate it back easily to the hit.
So use .DocumentsWithMetaData
for now, the next release will have a more logical API for highlights.
回答2:
here is an updated answer for version 7.x. You receive two collections as before, .Documents and .Hits . Within .Hits each one has an .Id that matches the _id of the index in elasticsearch. Note: if you request more than one highlighting .NumberofFragments in your query, you will just keep overwriting the result.title and result.content in the code below, so take this as a loose example to indicate how you can match the highlight result to the correct document result, and then overwrite the document field with the one containing the highlighting.
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();
}
}
}
}
}
}
来源:https://stackoverflow.com/questions/17805251/nest-elasticsearch-matching-highlights-to-documents