-
Notifications
You must be signed in to change notification settings - Fork 24.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wildcard field names in highlighting should only return fields that can be highlighted #11364
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,6 @@ | |
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.collect.ImmutableMap; | ||
import org.apache.lucene.index.IndexOptions; | ||
import org.apache.lucene.search.Query; | ||
import org.elasticsearch.common.component.AbstractComponent; | ||
import org.elasticsearch.common.inject.Inject; | ||
|
@@ -45,6 +44,8 @@ | |
*/ | ||
public class HighlightPhase extends AbstractComponent implements FetchSubPhase { | ||
|
||
private static final ImmutableList<String> STANDARD_HIGHLIGHTERS_BY_PRECEDENCE = ImmutableList.of("fvh", "postings", "plain"); | ||
|
||
private final Highlighters highlighters; | ||
|
||
@Inject | ||
|
@@ -91,6 +92,7 @@ public void hitExecute(SearchContext context, HitContext hitContext) { | |
} | ||
} | ||
|
||
boolean fieldNameContainsWildcards = field.field().contains("*"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should try and use the cannotHighlight method also when it comes to choosing the type of highlighter based on the field mapper (when no highlighter type is specified). Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, using the cannotHighlight methods now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a "resolve" button in github like there is in googledocs so we can ignore long resolved recommendations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. totally! |
||
for (String fieldName : fieldNamesToHighlight) { | ||
FieldMapper fieldMapper = getMapperForField(fieldName, context, hitContext); | ||
if (fieldMapper == null) { | ||
|
@@ -99,30 +101,32 @@ public void hitExecute(SearchContext context, HitContext hitContext) { | |
|
||
String highlighterType = field.fieldOptions().highlighterType(); | ||
if (highlighterType == null) { | ||
boolean useFastVectorHighlighter = fieldMapper.fieldType().storeTermVectors() && fieldMapper.fieldType().storeTermVectorOffsets() && fieldMapper.fieldType().storeTermVectorPositions(); | ||
if (useFastVectorHighlighter) { | ||
highlighterType = "fvh"; | ||
} else if (fieldMapper.fieldType().indexOptions() == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) { | ||
highlighterType = "postings"; | ||
} else { | ||
highlighterType = "plain"; | ||
for(String highlighterCandidate : STANDARD_HIGHLIGHTERS_BY_PRECEDENCE) { | ||
if (highlighters.get(highlighterCandidate).canHighlight(fieldMapper)) { | ||
highlighterType = highlighterCandidate; | ||
break; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add an assert to make sure that highlighterType != null here? it really should since we know that plain highlighter always returns true, but the assert would make it more explicit that it is expected There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense to me. The random null pointer exception you'd get later on if this went wrong would be unpleasant to users. Probably best to use an explicit check rather than an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather make it an assertion. it is an internal thing and should not happen at all. I have trouble coming up with a proper message that would even explain what is happening to a user... |
||
assert highlighterType != null; | ||
} | ||
|
||
Highlighter highlighter = highlighters.get(highlighterType); | ||
if (highlighter == null) { | ||
throw new IllegalArgumentException("unknown highlighter type [" + highlighterType + "] for the field [" + fieldName + "]"); | ||
} | ||
|
||
Query highlightQuery = field.fieldOptions().highlightQuery() == null ? context.parsedQuery().query() : field.fieldOptions().highlightQuery(); | ||
HighlighterContext highlighterContext = new HighlighterContext(fieldName, field, fieldMapper, context, hitContext, highlightQuery); | ||
|
||
if ((highlighter.canHighlight(fieldMapper) == false) && fieldNameContainsWildcards) { | ||
// if several fieldnames matched the wildcard then we want to skip those that we cannot highlight | ||
continue; | ||
} | ||
HighlightField highlightField = highlighter.highlight(highlighterContext); | ||
if (highlightField != null) { | ||
highlightFields.put(highlightField.name(), highlightField); | ||
} | ||
} | ||
} | ||
|
||
hitContext.hit().highlightFields(highlightFields); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,7 +50,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) { | |
|
||
FieldMapper fieldMapper = highlighterContext.mapper; | ||
SearchContextHighlight.Field field = highlighterContext.field; | ||
if (fieldMapper.fieldType().indexOptions() != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) { | ||
if (canHighlight(fieldMapper) == false) { | ||
throw new IllegalArgumentException("the field [" + highlighterContext.fieldName + "] should be indexed with positions and offsets in the postings list to be used with postings highlighter"); | ||
} | ||
|
||
|
@@ -126,6 +126,11 @@ public int compare(Snippet o1, Snippet o2) { | |
return null; | ||
} | ||
|
||
@Override | ||
public boolean canHighlight(FieldMapper fieldMapper) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing |
||
return fieldMapper.fieldType().indexOptions() == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS; | ||
} | ||
|
||
private static String mergeFieldValues(List<Object> fieldValues, char valuesSeparator) { | ||
//postings highlighter accepts all values in a single string, as offsets etc. need to match with content | ||
//loaded from stored fields, we merge all values using a proper separator | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!canHighlight(mapper)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the == false is done on purpose to make these comparisons more explicit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the comment usually the other way round with the argument that '== false' is much easier to read and a '!' is easy to miss so I'd rather leave it this way.