|
42 | 42 | import org.elasticsearch.index.query.QueryShardContext;
|
43 | 43 | import org.elasticsearch.script.Script;
|
44 | 44 | import org.elasticsearch.search.aggregations.AggregationBuilder;
|
| 45 | +import org.elasticsearch.search.slice.SliceBuilder; |
45 | 46 | import org.elasticsearch.search.aggregations.AggregatorFactories;
|
46 | 47 | import org.elasticsearch.search.aggregations.AggregatorParsers;
|
47 | 48 | import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
|
@@ -98,6 +99,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
|
98 | 99 | public static final ParseField EXT_FIELD = new ParseField("ext");
|
99 | 100 | public static final ParseField PROFILE_FIELD = new ParseField("profile");
|
100 | 101 | public static final ParseField SEARCH_AFTER = new ParseField("search_after");
|
| 102 | + public static final ParseField SLICE = new ParseField("slice"); |
101 | 103 |
|
102 | 104 | public static SearchSourceBuilder fromXContent(QueryParseContext context, AggregatorParsers aggParsers,
|
103 | 105 | Suggesters suggesters) throws IOException {
|
@@ -138,6 +140,8 @@ public static HighlightBuilder highlight() {
|
138 | 140 |
|
139 | 141 | private SearchAfterBuilder searchAfterBuilder;
|
140 | 142 |
|
| 143 | + private SliceBuilder sliceBuilder; |
| 144 | + |
141 | 145 | private Float minScore;
|
142 | 146 |
|
143 | 147 | private long timeoutInMillis = -1;
|
@@ -175,9 +179,7 @@ public SearchSourceBuilder() {
|
175 | 179 | * Read from a stream.
|
176 | 180 | */
|
177 | 181 | public SearchSourceBuilder(StreamInput in) throws IOException {
|
178 |
| - if (in.readBoolean()) { |
179 |
| - aggregations = new AggregatorFactories.Builder(in); |
180 |
| - } |
| 182 | + aggregations = in.readOptionalWriteable(AggregatorFactories.Builder::new); |
181 | 183 | explain = in.readOptionalBoolean();
|
182 | 184 | fetchSourceContext = in.readOptionalStreamable(FetchSourceContext::new);
|
183 | 185 | boolean hasFieldDataFields = in.readBoolean();
|
@@ -206,15 +208,9 @@ public SearchSourceBuilder(StreamInput in) throws IOException {
|
206 | 208 | indexBoost.put(in.readString(), in.readFloat());
|
207 | 209 | }
|
208 | 210 | }
|
209 |
| - if (in.readBoolean()) { |
210 |
| - minScore = in.readFloat(); |
211 |
| - } |
212 |
| - if (in.readBoolean()) { |
213 |
| - postQueryBuilder = in.readNamedWriteable(QueryBuilder.class); |
214 |
| - } |
215 |
| - if (in.readBoolean()) { |
216 |
| - queryBuilder = in.readNamedWriteable(QueryBuilder.class); |
217 |
| - } |
| 211 | + minScore = in.readOptionalFloat(); |
| 212 | + postQueryBuilder = in.readOptionalNamedWriteable(QueryBuilder.class); |
| 213 | + queryBuilder = in.readOptionalNamedWriteable(QueryBuilder.class); |
218 | 214 | if (in.readBoolean()) {
|
219 | 215 | int size = in.readVInt();
|
220 | 216 | rescoreBuilders = new ArrayList<>();
|
@@ -244,29 +240,20 @@ public SearchSourceBuilder(StreamInput in) throws IOException {
|
244 | 240 | stats.add(in.readString());
|
245 | 241 | }
|
246 | 242 | }
|
247 |
| - if (in.readBoolean()) { |
248 |
| - suggestBuilder = new SuggestBuilder(in); |
249 |
| - } |
| 243 | + suggestBuilder = in.readOptionalWriteable(SuggestBuilder::new); |
250 | 244 | terminateAfter = in.readVInt();
|
251 | 245 | timeoutInMillis = in.readLong();
|
252 | 246 | trackScores = in.readBoolean();
|
253 | 247 | version = in.readOptionalBoolean();
|
254 |
| - if (in.readBoolean()) { |
255 |
| - ext = in.readBytesReference(); |
256 |
| - } |
| 248 | + ext = in.readOptionalBytesReference(); |
257 | 249 | profile = in.readBoolean();
|
258 |
| - if (in.readBoolean()) { |
259 |
| - searchAfterBuilder = new SearchAfterBuilder(in); |
260 |
| - } |
| 250 | + searchAfterBuilder = in.readOptionalWriteable(SearchAfterBuilder::new); |
| 251 | + sliceBuilder = in.readOptionalWriteable(SliceBuilder::new); |
261 | 252 | }
|
262 | 253 |
|
263 | 254 | @Override
|
264 | 255 | public void writeTo(StreamOutput out) throws IOException {
|
265 |
| - boolean hasAggregations = aggregations != null; |
266 |
| - out.writeBoolean(hasAggregations); |
267 |
| - if (hasAggregations) { |
268 |
| - aggregations.writeTo(out); |
269 |
| - } |
| 256 | + out.writeOptionalWriteable(aggregations); |
270 | 257 | out.writeOptionalBoolean(explain);
|
271 | 258 | out.writeOptionalStreamable(fetchSourceContext);
|
272 | 259 | boolean hasFieldDataFields = fieldDataFields != null;
|
@@ -296,21 +283,9 @@ public void writeTo(StreamOutput out) throws IOException {
|
296 | 283 | out.writeFloat(indexBoost.get(key.value));
|
297 | 284 | }
|
298 | 285 | }
|
299 |
| - boolean hasMinScore = minScore != null; |
300 |
| - out.writeBoolean(hasMinScore); |
301 |
| - if (hasMinScore) { |
302 |
| - out.writeFloat(minScore); |
303 |
| - } |
304 |
| - boolean hasPostQuery = postQueryBuilder != null; |
305 |
| - out.writeBoolean(hasPostQuery); |
306 |
| - if (hasPostQuery) { |
307 |
| - out.writeNamedWriteable(postQueryBuilder); |
308 |
| - } |
309 |
| - boolean hasQuery = queryBuilder != null; |
310 |
| - out.writeBoolean(hasQuery); |
311 |
| - if (hasQuery) { |
312 |
| - out.writeNamedWriteable(queryBuilder); |
313 |
| - } |
| 286 | + out.writeOptionalFloat(minScore); |
| 287 | + out.writeOptionalNamedWriteable(postQueryBuilder); |
| 288 | + out.writeOptionalNamedWriteable(queryBuilder); |
314 | 289 | boolean hasRescoreBuilders = rescoreBuilders != null;
|
315 | 290 | out.writeBoolean(hasRescoreBuilders);
|
316 | 291 | if (hasRescoreBuilders) {
|
@@ -344,26 +319,15 @@ public void writeTo(StreamOutput out) throws IOException {
|
344 | 319 | out.writeString(stat);
|
345 | 320 | }
|
346 | 321 | }
|
347 |
| - boolean hasSuggestBuilder = suggestBuilder != null; |
348 |
| - out.writeBoolean(hasSuggestBuilder); |
349 |
| - if (hasSuggestBuilder) { |
350 |
| - suggestBuilder.writeTo(out); |
351 |
| - } |
| 322 | + out.writeOptionalWriteable(suggestBuilder); |
352 | 323 | out.writeVInt(terminateAfter);
|
353 | 324 | out.writeLong(timeoutInMillis);
|
354 | 325 | out.writeBoolean(trackScores);
|
355 | 326 | out.writeOptionalBoolean(version);
|
356 |
| - boolean hasExt = ext != null; |
357 |
| - out.writeBoolean(hasExt); |
358 |
| - if (hasExt) { |
359 |
| - out.writeBytesReference(ext); |
360 |
| - } |
| 327 | + out.writeOptionalBytesReference(ext); |
361 | 328 | out.writeBoolean(profile);
|
362 |
| - boolean hasSearchAfter = searchAfterBuilder != null; |
363 |
| - out.writeBoolean(hasSearchAfter); |
364 |
| - if (hasSearchAfter) { |
365 |
| - searchAfterBuilder.writeTo(out); |
366 |
| - } |
| 329 | + out.writeOptionalWriteable(searchAfterBuilder); |
| 330 | + out.writeOptionalWriteable(sliceBuilder); |
367 | 331 | }
|
368 | 332 |
|
369 | 333 | /**
|
@@ -597,6 +561,22 @@ public SearchSourceBuilder searchAfter(Object[] values) {
|
597 | 561 | return this;
|
598 | 562 | }
|
599 | 563 |
|
| 564 | + /** |
| 565 | + * Sets a filter that will restrict the search hits, the top hits and the aggregations to a slice of the results |
| 566 | + * of the main query. |
| 567 | + */ |
| 568 | + public SearchSourceBuilder slice(SliceBuilder builder) { |
| 569 | + this.sliceBuilder = builder; |
| 570 | + return this; |
| 571 | + } |
| 572 | + |
| 573 | + /** |
| 574 | + * Gets the slice used to filter the search hits, the top hits and the aggregations. |
| 575 | + */ |
| 576 | + public SliceBuilder slice() { |
| 577 | + return sliceBuilder; |
| 578 | + } |
| 579 | + |
600 | 580 | /**
|
601 | 581 | * Add an aggregation to perform as part of the search.
|
602 | 582 | */
|
@@ -943,6 +923,7 @@ private SearchSourceBuilder shallowCopy(QueryBuilder queryBuilder, QueryBuilder
|
943 | 923 | rewrittenBuilder.rescoreBuilders = rescoreBuilders;
|
944 | 924 | rewrittenBuilder.scriptFields = scriptFields;
|
945 | 925 | rewrittenBuilder.searchAfterBuilder = searchAfterBuilder;
|
| 926 | + rewrittenBuilder.sliceBuilder = sliceBuilder; |
946 | 927 | rewrittenBuilder.size = size;
|
947 | 928 | rewrittenBuilder.sorts = sorts;
|
948 | 929 | rewrittenBuilder.stats = stats;
|
@@ -1039,6 +1020,8 @@ public void parseXContent(QueryParseContext context, AggregatorParsers aggParser
|
1039 | 1020 | } else if (context.getParseFieldMatcher().match(currentFieldName, EXT_FIELD)) {
|
1040 | 1021 | XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().copyCurrentStructure(parser);
|
1041 | 1022 | ext = xContentBuilder.bytes();
|
| 1023 | + } else if (context.getParseFieldMatcher().match(currentFieldName, SLICE)) { |
| 1024 | + sliceBuilder = SliceBuilder.fromXContent(context); |
1042 | 1025 | } else {
|
1043 | 1026 | throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
|
1044 | 1027 | parser.getTokenLocation());
|
@@ -1193,6 +1176,10 @@ public void innerToXContent(XContentBuilder builder, Params params) throws IOExc
|
1193 | 1176 | builder.field(SEARCH_AFTER.getPreferredName(), searchAfterBuilder.getSortValues());
|
1194 | 1177 | }
|
1195 | 1178 |
|
| 1179 | + if (sliceBuilder != null) { |
| 1180 | + builder.field(SLICE.getPreferredName(), sliceBuilder); |
| 1181 | + } |
| 1182 | + |
1196 | 1183 | if (indexBoost != null) {
|
1197 | 1184 | builder.startObject(INDICES_BOOST_FIELD.getPreferredName());
|
1198 | 1185 | assert !indexBoost.containsKey(null);
|
@@ -1355,7 +1342,7 @@ public boolean equals(Object obj) {
|
1355 | 1342 | public int hashCode() {
|
1356 | 1343 | return Objects.hash(aggregations, explain, fetchSourceContext, fieldDataFields, fieldNames, from,
|
1357 | 1344 | highlightBuilder, indexBoost, minScore, postQueryBuilder, queryBuilder, rescoreBuilders, scriptFields,
|
1358 |
| - size, sorts, searchAfterBuilder, stats, suggestBuilder, terminateAfter, timeoutInMillis, trackScores, version, profile); |
| 1345 | + size, sorts, searchAfterBuilder, sliceBuilder, stats, suggestBuilder, terminateAfter, timeoutInMillis, trackScores, version, profile); |
1359 | 1346 | }
|
1360 | 1347 |
|
1361 | 1348 | @Override
|
@@ -1383,6 +1370,7 @@ public boolean equals(Object obj) {
|
1383 | 1370 | && Objects.equals(size, other.size)
|
1384 | 1371 | && Objects.equals(sorts, other.sorts)
|
1385 | 1372 | && Objects.equals(searchAfterBuilder, other.searchAfterBuilder)
|
| 1373 | + && Objects.equals(sliceBuilder, other.sliceBuilder) |
1386 | 1374 | && Objects.equals(stats, other.stats)
|
1387 | 1375 | && Objects.equals(suggestBuilder, other.suggestBuilder)
|
1388 | 1376 | && Objects.equals(terminateAfter, other.terminateAfter)
|
|
0 commit comments