Skip to content

Commit dd0b428

Browse files
synhershkos1monw
authored andcommitted
[QUERY] Separate parsing impl from setter in SearchParseElement
This commit makes it easier to reuse the inner highlighting, fetch and rescore parsing logic by plugins or other internal parts. Closes elastic#3602
1 parent d403e68 commit dd0b428

File tree

3 files changed

+35
-25
lines changed

3 files changed

+35
-25
lines changed

src/main/java/org/elasticsearch/search/fetch/source/FetchSourceParseElement.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.elasticsearch.search.SearchParseElement;
2626
import org.elasticsearch.search.internal.SearchContext;
2727

28+
import java.io.IOException;
2829
import java.util.ArrayList;
2930
import java.util.List;
3031

@@ -43,17 +44,19 @@ public class FetchSourceParseElement implements SearchParseElement {
4344

4445
@Override
4546
public void parse(XContentParser parser, SearchContext context) throws Exception {
47+
context.fetchSourceContext(parse(parser));
48+
}
49+
50+
public FetchSourceContext parse(XContentParser parser) throws IOException {
4651
XContentParser.Token token;
4752

4853
List<String> includes = null, excludes = null;
4954
String currentFieldName = null;
5055
token = parser.currentToken(); // we get it on the value
5156
if (parser.isBooleanValue()) {
52-
context.fetchSourceContext(new FetchSourceContext(parser.booleanValue()));
53-
return;
57+
return new FetchSourceContext(parser.booleanValue());
5458
} else if (token == XContentParser.Token.VALUE_STRING) {
55-
context.fetchSourceContext(new FetchSourceContext(new String[]{parser.text()}));
56-
return;
59+
return new FetchSourceContext(new String[]{parser.text()});
5760
} else if (token == XContentParser.Token.START_ARRAY) {
5861
includes = new ArrayList<>();
5962
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
@@ -87,10 +90,8 @@ public void parse(XContentParser parser, SearchContext context) throws Exception
8790
throw new ElasticsearchParseException("source element value can be of type " + token.name());
8891
}
8992

90-
91-
context.fetchSourceContext(new FetchSourceContext(
93+
return new FetchSourceContext(
9294
includes == null ? Strings.EMPTY_ARRAY : includes.toArray(new String[includes.size()]),
93-
excludes == null ? Strings.EMPTY_ARRAY : excludes.toArray(new String[excludes.size()])));
94-
95+
excludes == null ? Strings.EMPTY_ARRAY : excludes.toArray(new String[excludes.size()]));
9596
}
9697
}

src/main/java/org/elasticsearch/search/highlight/HighlighterParseElement.java

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import com.google.common.collect.Lists;
2323
import com.google.common.collect.Sets;
2424
import org.apache.lucene.search.vectorhighlight.SimpleBoundaryScanner;
25+
import org.elasticsearch.ElasticsearchIllegalArgumentException;
2526
import org.elasticsearch.common.collect.Tuple;
2627
import org.elasticsearch.common.xcontent.XContentParser;
28+
import org.elasticsearch.index.query.IndexQueryParserService;
2729
import org.elasticsearch.search.SearchParseElement;
2830
import org.elasticsearch.search.SearchParseException;
2931
import org.elasticsearch.search.internal.SearchContext;
@@ -66,11 +68,19 @@ public class HighlighterParseElement implements SearchParseElement {
6668

6769
@Override
6870
public void parse(XContentParser parser, SearchContext context) throws Exception {
71+
try {
72+
context.highlight(parse(parser, context.queryParserService()));
73+
} catch (ElasticsearchIllegalArgumentException ex) {
74+
throw new SearchParseException(context, "Error while trying to parse Highlighter element in request");
75+
}
76+
}
77+
78+
public SearchContextHighlight parse(XContentParser parser, IndexQueryParserService queryParserService) throws IOException {
6979
XContentParser.Token token;
7080
String topLevelFieldName = null;
71-
List<Tuple<String, SearchContextHighlight.FieldOptions.Builder>> fieldsOptions = newArrayList();
81+
final List<Tuple<String, SearchContextHighlight.FieldOptions.Builder>> fieldsOptions = newArrayList();
7282

73-
SearchContextHighlight.FieldOptions.Builder globalOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder()
83+
final SearchContextHighlight.FieldOptions.Builder globalOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder()
7484
.preTags(DEFAULT_PRE_TAGS).postTags(DEFAULT_POST_TAGS).scoreOrdered(false).highlightFilter(false)
7585
.requireFieldMatch(false).forceSource(false).fragmentCharSize(100).numberOfFragments(5)
7686
.encoder("default").boundaryMaxScan(SimpleBoundaryScanner.DEFAULT_MAX_SCAN)
@@ -100,15 +110,15 @@ public void parse(XContentParser parser, SearchContext context) throws Exception
100110
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
101111
if (token == XContentParser.Token.FIELD_NAME) {
102112
if (highlightFieldName != null) {
103-
throw new SearchParseException(context, "If highlighter fields is an array it must contain objects containing a single field");
113+
throw new ElasticsearchIllegalArgumentException("If highlighter fields is an array it must contain objects containing a single field");
104114
}
105115
highlightFieldName = parser.currentName();
106116
} else if (token == XContentParser.Token.START_OBJECT) {
107-
fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, context)));
117+
fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, queryParserService)));
108118
}
109119
}
110120
} else {
111-
throw new SearchParseException(context, "If highlighter fields is an array it must contain objects containing a single field");
121+
throw new ElasticsearchIllegalArgumentException("If highlighter fields is an array it must contain objects containing a single field");
112122
}
113123
}
114124
}
@@ -160,33 +170,32 @@ public void parse(XContentParser parser, SearchContext context) throws Exception
160170
if (token == XContentParser.Token.FIELD_NAME) {
161171
highlightFieldName = parser.currentName();
162172
} else if (token == XContentParser.Token.START_OBJECT) {
163-
fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, context)));
173+
fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, queryParserService)));
164174
}
165175
}
166176
} else if ("highlight_query".equals(topLevelFieldName) || "highlightQuery".equals(topLevelFieldName)) {
167-
globalOptionsBuilder.highlightQuery(context.queryParserService().parse(parser).query());
177+
globalOptionsBuilder.highlightQuery(queryParserService.parse(parser).query());
168178
}
169179
}
170180
}
171181

172-
SearchContextHighlight.FieldOptions globalOptions = globalOptionsBuilder.build();
182+
final SearchContextHighlight.FieldOptions globalOptions = globalOptionsBuilder.build();
173183
if (globalOptions.preTags() != null && globalOptions.postTags() == null) {
174-
throw new SearchParseException(context, "Highlighter global preTags are set, but global postTags are not set");
184+
throw new ElasticsearchIllegalArgumentException("Highlighter global preTags are set, but global postTags are not set");
175185
}
176186

177-
List<SearchContextHighlight.Field> fields = Lists.newArrayList();
187+
final List<SearchContextHighlight.Field> fields = Lists.newArrayList();
178188
// now, go over and fill all fieldsOptions with default values from the global state
179-
for (Tuple<String, SearchContextHighlight.FieldOptions.Builder> tuple : fieldsOptions) {
189+
for (final Tuple<String, SearchContextHighlight.FieldOptions.Builder> tuple : fieldsOptions) {
180190
fields.add(new SearchContextHighlight.Field(tuple.v1(), tuple.v2().merge(globalOptions).build()));
181191
}
182-
183-
context.highlight(new SearchContextHighlight(fields));
192+
return new SearchContextHighlight(fields);
184193
}
185194

186-
private SearchContextHighlight.FieldOptions.Builder parseFields(XContentParser parser, SearchContext context) throws IOException {
195+
protected SearchContextHighlight.FieldOptions.Builder parseFields(XContentParser parser, IndexQueryParserService queryParserService) throws IOException {
187196
XContentParser.Token token;
188197

189-
SearchContextHighlight.FieldOptions.Builder fieldOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder();
198+
final SearchContextHighlight.FieldOptions.Builder fieldOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder();
190199
String fieldName = null;
191200
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
192201
if (token == XContentParser.Token.FIELD_NAME) {
@@ -246,7 +255,7 @@ private SearchContextHighlight.FieldOptions.Builder parseFields(XContentParser p
246255
}
247256
} else if (token == XContentParser.Token.START_OBJECT) {
248257
if ("highlight_query".equals(fieldName) || "highlightQuery".equals(fieldName)) {
249-
fieldOptionsBuilder.highlightQuery(context.queryParserService().parse(parser).query());
258+
fieldOptionsBuilder.highlightQuery(queryParserService.parse(parser).query());
250259
} else if ("options".equals(fieldName)) {
251260
fieldOptionsBuilder.options(parser.map());
252261
}

src/main/java/org/elasticsearch/search/rescore/RescoreParseElement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void parse(XContentParser parser, SearchContext context) throws Exception
4141
}
4242
}
4343

44-
private void parseSingleRescoreContext(XContentParser parser, SearchContext context) throws Exception {
44+
public void parseSingleRescoreContext(XContentParser parser, SearchContext context) throws Exception {
4545
String fieldName = null;
4646
RescoreSearchContext rescoreContext = null;
4747
Integer windowSize = null;

0 commit comments

Comments
 (0)