Skip to content

Commit 31e88ef

Browse files
committed
In the internal highlighter APIs, use the field type as opposed to the mapper. (#31039)
(cherry picked from commit 609de08)
1 parent 56bf0e2 commit 31e88ef

File tree

12 files changed

+110
-108
lines changed

12 files changed

+110
-108
lines changed

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import org.elasticsearch.common.settings.Setting;
3737
import org.elasticsearch.common.settings.Settings;
3838
import org.elasticsearch.common.text.Text;
39-
import org.elasticsearch.index.mapper.FieldMapper;
39+
import org.elasticsearch.index.mapper.MappedFieldType;
4040
import org.elasticsearch.search.fetch.FetchPhaseExecutionException;
4141
import org.elasticsearch.search.fetch.FetchSubPhase;
4242
import org.elasticsearch.search.fetch.subphase.highlight.SearchContextHighlight.Field;
@@ -71,9 +71,9 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
7171
SearchContextHighlight.Field field = highlighterContext.field;
7272
SearchContext context = highlighterContext.context;
7373
FetchSubPhase.HitContext hitContext = highlighterContext.hitContext;
74-
FieldMapper mapper = highlighterContext.mapper;
74+
MappedFieldType fieldType = highlighterContext.fieldType;
7575

76-
if (canHighlight(mapper) == false) {
76+
if (canHighlight(fieldType) == false) {
7777
throw new IllegalArgumentException("the field [" + highlighterContext.fieldName +
7878
"] should be indexed with term vector with position offsets to be used with fast vector highlighter");
7979
}
@@ -87,7 +87,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
8787
HighlighterEntry cache = (HighlighterEntry) hitContext.cache().get(CACHE_KEY);
8888

8989
try {
90-
MapperHighlightEntry entry = cache.mappers.get(mapper);
90+
FieldHighlightEntry entry = cache.fields.get(fieldType);
9191
if (entry == null) {
9292
FragListBuilder fragListBuilder;
9393
BaseFragmentsBuilder fragmentsBuilder;
@@ -97,37 +97,37 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
9797
if (field.fieldOptions().numberOfFragments() == 0) {
9898
fragListBuilder = new SingleFragListBuilder();
9999

100-
if (!forceSource && mapper.fieldType().stored()) {
101-
fragmentsBuilder = new SimpleFragmentsBuilder(mapper, field.fieldOptions().preTags(),
100+
if (!forceSource && fieldType.stored()) {
101+
fragmentsBuilder = new SimpleFragmentsBuilder(fieldType, field.fieldOptions().preTags(),
102102
field.fieldOptions().postTags(), boundaryScanner);
103103
} else {
104-
fragmentsBuilder = new SourceSimpleFragmentsBuilder(mapper, context,
104+
fragmentsBuilder = new SourceSimpleFragmentsBuilder(fieldType, context,
105105
field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner);
106106
}
107107
} else {
108108
fragListBuilder = field.fieldOptions().fragmentOffset() == -1 ?
109109
new SimpleFragListBuilder() : new SimpleFragListBuilder(field.fieldOptions().fragmentOffset());
110110
if (field.fieldOptions().scoreOrdered()) {
111-
if (!forceSource && mapper.fieldType().stored()) {
111+
if (!forceSource && fieldType.stored()) {
112112
fragmentsBuilder = new ScoreOrderFragmentsBuilder(field.fieldOptions().preTags(),
113113
field.fieldOptions().postTags(), boundaryScanner);
114114
} else {
115-
fragmentsBuilder = new SourceScoreOrderFragmentsBuilder(mapper, context,
115+
fragmentsBuilder = new SourceScoreOrderFragmentsBuilder(fieldType, context,
116116
field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner);
117117
}
118118
} else {
119-
if (!forceSource && mapper.fieldType().stored()) {
120-
fragmentsBuilder = new SimpleFragmentsBuilder(mapper, field.fieldOptions().preTags(),
119+
if (!forceSource && fieldType.stored()) {
120+
fragmentsBuilder = new SimpleFragmentsBuilder(fieldType, field.fieldOptions().preTags(),
121121
field.fieldOptions().postTags(), boundaryScanner);
122122
} else {
123123
fragmentsBuilder =
124-
new SourceSimpleFragmentsBuilder(mapper, context, field.fieldOptions().preTags(),
124+
new SourceSimpleFragmentsBuilder(fieldType, context, field.fieldOptions().preTags(),
125125
field.fieldOptions().postTags(), boundaryScanner);
126126
}
127127
}
128128
}
129129
fragmentsBuilder.setDiscreteMultiValueHighlighting(termVectorMultiValue);
130-
entry = new MapperHighlightEntry();
130+
entry = new FieldHighlightEntry();
131131
if (field.fieldOptions().requireFieldMatch()) {
132132
/**
133133
* we use top level reader to rewrite the query against all readers,
@@ -152,7 +152,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
152152
cache.fvh = new org.apache.lucene.search.vectorhighlight.FastVectorHighlighter();
153153
}
154154
CustomFieldQuery.highlightFilters.set(field.fieldOptions().highlightFilter());
155-
cache.mappers.put(mapper, entry);
155+
cache.fields.put(fieldType, entry);
156156
}
157157
final FieldQuery fieldQuery;
158158
if (field.fieldOptions().requireFieldMatch()) {
@@ -173,12 +173,12 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
173173
// Only send matched fields if they were requested to save time.
174174
if (field.fieldOptions().matchedFields() != null && !field.fieldOptions().matchedFields().isEmpty()) {
175175
fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(),
176-
mapper.fieldType().name(), field.fieldOptions().matchedFields(), fragmentCharSize,
176+
fieldType.name(), field.fieldOptions().matchedFields(), fragmentCharSize,
177177
numberOfFragments, entry.fragListBuilder, entry.fragmentsBuilder, field.fieldOptions().preTags(),
178178
field.fieldOptions().postTags(), encoder);
179179
} else {
180180
fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(),
181-
mapper.fieldType().name(), fragmentCharSize, numberOfFragments, entry.fragListBuilder,
181+
fieldType.name(), fragmentCharSize, numberOfFragments, entry.fragListBuilder,
182182
entry.fragmentsBuilder, field.fieldOptions().preTags(), field.fieldOptions().postTags(), encoder);
183183
}
184184

@@ -193,7 +193,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
193193
FieldFragList fieldFragList = new SimpleFieldFragList(-1 /*ignored*/);
194194
fieldFragList.add(0, noMatchSize, Collections.<WeightedPhraseInfo>emptyList());
195195
fragments = entry.fragmentsBuilder.createFragments(hitContext.reader(), hitContext.docId(),
196-
mapper.fieldType().name(), fieldFragList, 1, field.fieldOptions().preTags(),
196+
fieldType.name(), fieldFragList, 1, field.fieldOptions().preTags(),
197197
field.fieldOptions().postTags(), encoder);
198198
if (fragments != null && fragments.length > 0) {
199199
return new HighlightField(highlighterContext.fieldName, Text.convertFromStringArray(fragments));
@@ -209,9 +209,10 @@ public HighlightField highlight(HighlighterContext highlighterContext) {
209209
}
210210

211211
@Override
212-
public boolean canHighlight(FieldMapper fieldMapper) {
213-
return fieldMapper.fieldType().storeTermVectors() && fieldMapper.fieldType().storeTermVectorOffsets()
214-
&& fieldMapper.fieldType().storeTermVectorPositions();
212+
public boolean canHighlight(MappedFieldType fieldType) {
213+
return fieldType.storeTermVectors()
214+
&& fieldType.storeTermVectorOffsets()
215+
&& fieldType.storeTermVectorPositions();
215216
}
216217

217218
private static BoundaryScanner getBoundaryScanner(Field field) {
@@ -244,7 +245,7 @@ private static BoundaryScanner getBoundaryScanner(Field field) {
244245
}
245246
}
246247

247-
private class MapperHighlightEntry {
248+
private class FieldHighlightEntry {
248249
public FragListBuilder fragListBuilder;
249250
public FragmentsBuilder fragmentsBuilder;
250251
public FieldQuery noFieldMatchFieldQuery;
@@ -253,6 +254,6 @@ private class MapperHighlightEntry {
253254

254255
private class HighlighterEntry {
255256
public org.apache.lucene.search.vectorhighlight.FastVectorHighlighter fvh;
256-
public Map<FieldMapper, MapperHighlightEntry> mappers = new HashMap<>();
257+
public Map<MappedFieldType, FieldHighlightEntry> fields = new HashMap<>();
257258
}
258259
}

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FragmentBuilderHelper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.elasticsearch.index.analysis.CustomAnalyzer;
3030
import org.elasticsearch.index.analysis.NamedAnalyzer;
3131
import org.elasticsearch.index.analysis.TokenFilterFactory;
32-
import org.elasticsearch.index.mapper.FieldMapper;
32+
import org.elasticsearch.index.mapper.MappedFieldType;
3333

3434
import java.util.Comparator;
3535
import java.util.List;
@@ -47,10 +47,10 @@ private FragmentBuilderHelper() {
4747
* Fixes problems with broken analysis chains if positions and offsets are messed up that can lead to
4848
* {@link StringIndexOutOfBoundsException} in the {@link FastVectorHighlighter}
4949
*/
50-
public static WeightedFragInfo fixWeightedFragInfo(FieldMapper mapper, Field[] values, WeightedFragInfo fragInfo) {
50+
public static WeightedFragInfo fixWeightedFragInfo(MappedFieldType fieldType, Field[] values, WeightedFragInfo fragInfo) {
5151
assert fragInfo != null : "FragInfo must not be null";
52-
assert mapper.fieldType().name().equals(values[0].name()) : "Expected FieldMapper for field " + values[0].name();
53-
if (!fragInfo.getSubInfos().isEmpty() && containsBrokenAnalysis(mapper.fieldType().indexAnalyzer())) {
52+
assert fieldType.name().equals(values[0].name()) : "Expected MappedFieldType for field " + values[0].name();
53+
if (!fragInfo.getSubInfos().isEmpty() && containsBrokenAnalysis(fieldType.indexAnalyzer())) {
5454
/* This is a special case where broken analysis like WDF is used for term-vector creation at index-time
5555
* which can potentially mess up the offsets. To prevent a SAIIOBException we need to resort
5656
* the fragments based on their offsets rather than using soley the positions as it is done in

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,16 @@
2424
import org.elasticsearch.common.regex.Regex;
2525
import org.elasticsearch.common.settings.Settings;
2626
import org.elasticsearch.index.mapper.DocumentMapper;
27-
import org.elasticsearch.index.mapper.FieldMapper;
2827
import org.elasticsearch.index.mapper.KeywordFieldMapper;
28+
import org.elasticsearch.index.mapper.MappedFieldType;
2929
import org.elasticsearch.index.mapper.SourceFieldMapper;
3030
import org.elasticsearch.index.mapper.TextFieldMapper;
3131
import org.elasticsearch.search.fetch.FetchSubPhase;
3232
import org.elasticsearch.search.internal.SearchContext;
3333

34-
import java.util.Arrays;
3534
import java.util.Collection;
3635
import java.util.Collections;
3736
import java.util.HashMap;
38-
import java.util.List;
3937
import java.util.Map;
4038

4139
public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
@@ -71,8 +69,8 @@ public void hitExecute(SearchContext context, HitContext hitContext) {
7169

7270
boolean fieldNameContainsWildcards = field.field().contains("*");
7371
for (String fieldName : fieldNamesToHighlight) {
74-
FieldMapper fieldMapper = getMapperForField(fieldName, context, hitContext);
75-
if (fieldMapper == null) {
72+
MappedFieldType fieldType = context.mapperService().fullName(fieldName);
73+
if (fieldType == null) {
7674
continue;
7775
}
7876

@@ -85,8 +83,8 @@ public void hitExecute(SearchContext context, HitContext hitContext) {
8583
// If the field was explicitly given we assume that whoever issued the query knew
8684
// what they were doing and try to highlight anyway.
8785
if (fieldNameContainsWildcards) {
88-
if (fieldMapper.fieldType().typeName().equals(TextFieldMapper.CONTENT_TYPE) == false &&
89-
fieldMapper.fieldType().typeName().equals(KeywordFieldMapper.CONTENT_TYPE) == false) {
86+
if (fieldType.typeName().equals(TextFieldMapper.CONTENT_TYPE) == false &&
87+
fieldType.typeName().equals(KeywordFieldMapper.CONTENT_TYPE) == false) {
9088
continue;
9189
}
9290
}
@@ -104,10 +102,10 @@ public void hitExecute(SearchContext context, HitContext hitContext) {
104102
if (highlightQuery == null) {
105103
highlightQuery = context.parsedQuery().query();
106104
}
107-
HighlighterContext highlighterContext = new HighlighterContext(fieldName, field, fieldMapper, context,
108-
hitContext, highlightQuery);
105+
HighlighterContext highlighterContext = new HighlighterContext(fieldName,
106+
field, fieldType, context, hitContext, highlightQuery);
109107

110-
if ((highlighter.canHighlight(fieldMapper) == false) && fieldNameContainsWildcards) {
108+
if ((highlighter.canHighlight(fieldType) == false) && fieldNameContainsWildcards) {
111109
// if several fieldnames matched the wildcard then we want to skip those that we cannot highlight
112110
continue;
113111
}
@@ -119,10 +117,4 @@ public void hitExecute(SearchContext context, HitContext hitContext) {
119117
}
120118
hitContext.hit().highlightFields(highlightFields);
121119
}
122-
123-
private FieldMapper getMapperForField(String fieldName, SearchContext searchContext, HitContext hitContext) {
124-
DocumentMapper documentMapper = searchContext.mapperService().documentMapper(hitContext.hit().getType());
125-
// TODO: no need to lookup the doc mapper with unambiguous field names? just look at the mapper service
126-
return documentMapper.mappers().smartNameFieldMapper(fieldName);
127-
}
128120
}

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import org.apache.lucene.search.highlight.Encoder;
2323
import org.apache.lucene.search.highlight.SimpleHTMLEncoder;
2424
import org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor;
25-
import org.elasticsearch.index.mapper.FieldMapper;
25+
import org.elasticsearch.index.mapper.MappedFieldType;
2626
import org.elasticsearch.search.fetch.FetchSubPhase;
2727
import org.elasticsearch.search.internal.SearchContext;
2828
import org.elasticsearch.search.lookup.SourceLookup;
@@ -46,23 +46,25 @@ private HighlightUtils() {
4646
/**
4747
* Load field values for highlighting.
4848
*/
49-
public static List<Object> loadFieldValues(SearchContextHighlight.Field field, FieldMapper mapper, SearchContext searchContext,
50-
FetchSubPhase.HitContext hitContext) throws IOException {
49+
public static List<Object> loadFieldValues(SearchContextHighlight.Field field,
50+
MappedFieldType fieldType,
51+
SearchContext searchContext,
52+
FetchSubPhase.HitContext hitContext) throws IOException {
5153
//percolator needs to always load from source, thus it sets the global force source to true
5254
boolean forceSource = searchContext.highlight().forceSource(field);
5355
List<Object> textsToHighlight;
54-
if (!forceSource && mapper.fieldType().stored()) {
55-
CustomFieldsVisitor fieldVisitor = new CustomFieldsVisitor(singleton(mapper.fieldType().name()), false);
56+
if (!forceSource && fieldType.stored()) {
57+
CustomFieldsVisitor fieldVisitor = new CustomFieldsVisitor(singleton(fieldType.name()), false);
5658
hitContext.reader().document(hitContext.docId(), fieldVisitor);
57-
textsToHighlight = fieldVisitor.fields().get(mapper.fieldType().name());
59+
textsToHighlight = fieldVisitor.fields().get(fieldType.name());
5860
if (textsToHighlight == null) {
5961
// Can happen if the document doesn't have the field to highlight
6062
textsToHighlight = Collections.emptyList();
6163
}
6264
} else {
6365
SourceLookup sourceLookup = searchContext.lookup().source();
6466
sourceLookup.setSegmentAndDocument(hitContext.readerContext(), hitContext.docId());
65-
textsToHighlight = sourceLookup.extractRawValues(mapper.fieldType().name());
67+
textsToHighlight = sourceLookup.extractRawValues(fieldType.name());
6668
}
6769
assert textsToHighlight != null;
6870
return textsToHighlight;

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/Highlighter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
package org.elasticsearch.search.fetch.subphase.highlight;
2020

21-
import org.elasticsearch.index.mapper.FieldMapper;
21+
import org.elasticsearch.index.mapper.MappedFieldType;
2222

2323
/**
2424
* Highlights a search result.
@@ -27,5 +27,5 @@ public interface Highlighter {
2727

2828
HighlightField highlight(HighlighterContext highlighterContext);
2929

30-
boolean canHighlight(FieldMapper fieldMapper);
30+
boolean canHighlight(MappedFieldType fieldType);
3131
}

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterContext.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,28 @@
1919
package org.elasticsearch.search.fetch.subphase.highlight;
2020

2121
import org.apache.lucene.search.Query;
22-
import org.elasticsearch.index.mapper.FieldMapper;
22+
import org.elasticsearch.index.mapper.MappedFieldType;
2323
import org.elasticsearch.search.fetch.FetchSubPhase;
2424
import org.elasticsearch.search.internal.SearchContext;
2525

2626
public class HighlighterContext {
2727

2828
public final String fieldName;
2929
public final SearchContextHighlight.Field field;
30-
public final FieldMapper mapper;
30+
public final MappedFieldType fieldType;
3131
public final SearchContext context;
3232
public final FetchSubPhase.HitContext hitContext;
3333
public final Query query;
3434

35-
public HighlighterContext(String fieldName, SearchContextHighlight.Field field, FieldMapper mapper, SearchContext context,
36-
FetchSubPhase.HitContext hitContext, Query query) {
35+
public HighlighterContext(String fieldName,
36+
SearchContextHighlight.Field field,
37+
MappedFieldType fieldType,
38+
SearchContext context,
39+
FetchSubPhase.HitContext hitContext,
40+
Query query) {
3741
this.fieldName = fieldName;
3842
this.field = field;
39-
this.mapper = mapper;
43+
this.fieldType = fieldType;
4044
this.context = context;
4145
this.hitContext = hitContext;
4246
this.query = query;

0 commit comments

Comments
 (0)