Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
e867b60
add wrapper object for a single query
jdconrad May 16, 2023
ef1a959
add wrapper for search queries to carry enough information to do
jdconrad May 17, 2023
3c2d6bd
add paths for dfs and no dfs phases
jdconrad May 18, 2023
97f465d
Merge branch 'main' into rrfmulti
jdconrad May 18, 2023
541b6c1
fix npe
jdconrad May 18, 2023
e7971e1
another npe
jdconrad May 18, 2023
3bb28ce
fix test
jdconrad May 18, 2023
17311de
fix npe
jdconrad May 18, 2023
56a5602
make version high to avoid conflicts for now
jdconrad May 22, 2023
3dc0b8b
Merge branch 'main' into rrfmulti
jdconrad May 22, 2023
fdc27a7
fix transport version id
jdconrad May 22, 2023
188c6f6
add an it test for 2 bm25 queries as part of rrf
jdconrad May 22, 2023
03568c1
fix test
jdconrad May 22, 2023
649e778
fix test
jdconrad May 22, 2023
e0e4ee2
Merge branch 'main' into rrfmulti
jdconrad May 22, 2023
ad95da3
add restriction for query and queries used at the same time
jdconrad May 23, 2023
70f673c
Add tests for SearchQueryBuilder
jdconrad May 23, 2023
26f2883
rename SearchQuery to SearchQueryWrapper
jdconrad May 23, 2023
5315d0e
remove dead code
jdconrad May 23, 2023
e0ec23e
do not use single shard shortcut when using rank
jdconrad May 24, 2023
e18cf29
Merge branch 'main' into rrfmulti
jdconrad May 24, 2023
8fa9c52
update shard counts
jdconrad May 24, 2023
807f654
add additional check for single shard optimization to not run with rank
jdconrad May 24, 2023
9a06051
spotless
jdconrad May 24, 2023
0d6dbeb
Merge branch 'main' into rrfmulti
jdconrad May 25, 2023
9424ef6
Merge branch 'main' into rrfmulti
jdconrad May 25, 2023
6c9e87b
Merge branch 'main' into rrfmulti
jdconrad May 25, 2023
b7c75e1
add logic for queries to can match
jdconrad May 25, 2023
a32b488
spotless
jdconrad May 25, 2023
3dfae23
Merge branch 'main' into rrfmulti
jdconrad May 25, 2023
baef214
fix can match issue with empty queries
jdconrad May 25, 2023
e32d50c
Merge branch 'main' into rrfmulti
jdconrad May 26, 2023
2776684
Merge branch 'main' into rrfmulti
jdconrad May 30, 2023
fe637c9
Merge branch 'main' into rrfmulti
jdconrad May 30, 2023
f467433
add tests with multi bm25 queries and knn searches
jdconrad May 30, 2023
b60cd61
add rrf tests for coordinator can match
jdconrad Jun 1, 2023
3735fb3
Merge branch 'main' into rrfmulti
jdconrad Jun 1, 2023
841b0bb
add tests for shard can match
jdconrad Jun 2, 2023
c74e6fc
move cluster setup to single test
jdconrad Jun 2, 2023
26c680b
Merge branch 'main' into rrfmulti
jdconrad Jun 2, 2023
c7b8d31
add some basic yaml test for rrf with multiple queries
jdconrad Jun 2, 2023
f43555c
add it for linear combination with queries
jdconrad Jun 2, 2023
f93fb93
resolve ambiguity in multi shard from identitical score
jdconrad Jun 2, 2023
b396353
Update docs/changelog/96224.yaml
jdconrad Jun 2, 2023
9a80229
Merge branch 'main' into rrfmulti
jdconrad Jun 5, 2023
a63a47d
Merge branch 'main' into rrfmulti
jdconrad Jun 5, 2023
1e626f7
Merge branch 'main' into rrfmulti
jdconrad Jun 5, 2023
b5e5a9e
Merge branch 'main' into rrfmulti
jdconrad Jun 7, 2023
0739193
Merge branch 'main' into rrfmulti
jdconrad Jun 12, 2023
143357d
response to pr comments
jdconrad Jun 12, 2023
1235aa3
fix validate test
jdconrad Jun 12, 2023
f5801b1
add queries parameter to random source builder for tests
jdconrad Jun 12, 2023
81b677c
remove SearchQueryWrapper
jdconrad Jun 12, 2023
68f8911
Merge branch 'main' into rrfmulti
jdconrad Jun 12, 2023
a3682e1
fix tests
jdconrad Jun 12, 2023
babafdf
require rank to use queries
jdconrad Jun 12, 2023
ccd63b1
disallow linear combination with queries
jdconrad Jun 13, 2023
c5d5e76
remove linear combination queries tests
jdconrad Jun 13, 2023
fb2efeb
Merge branch 'main' into rrfmulti
jdconrad Jun 13, 2023
d0f3c3e
rename SearchQueryWrapperBuilder to SubSearchQueryBuilder
jdconrad Jun 13, 2023
4bcde34
spotless
jdconrad Jun 13, 2023
b2b9c96
Merge branch 'main' into rrfmulti
jdconrad Jun 13, 2023
43070f6
fix transport version
jdconrad Jun 13, 2023
d552c3c
change name
jdconrad Jun 13, 2023
a8aae3a
fix accidental line deletion
jdconrad Jun 13, 2023
b3afe73
fix unit tests
jdconrad Jun 13, 2023
9987b05
move multi query logic to shards
jdconrad Jun 13, 2023
b969149
fix bwc issues and update SearchSourceBuilder to only use queries as a
jdconrad Jun 13, 2023
5969916
fix named write
jdconrad Jun 13, 2023
7c2bf13
fix validation test
jdconrad Jun 13, 2023
c7d924d
Merge branch 'main' into rrfmulti
jdconrad Jun 13, 2023
c248c33
remove extraneous commented out variable
jdconrad Jun 13, 2023
7a20d0a
fix serialization test
jdconrad Jun 13, 2023
e0aa9bf
fix SearchSourceBuilder equals and hashcode
jdconrad Jun 14, 2023
79811bd
only write rank query builders to prior verisons if rank is set
jdconrad Jun 14, 2023
82d5be6
Merge branch 'main' into rrfmulti
jdconrad Jun 14, 2023
754fa18
fix unit test
jdconrad Jun 14, 2023
60e0bfe
spotless
jdconrad Jun 14, 2023
b78b395
Merge branch 'main' into rrfmulti
jdconrad Jun 14, 2023
faeb437
fix serialization bug
jdconrad Jun 14, 2023
087467d
Merge branch 'main' into rrfmulti
jdconrad Jun 15, 2023
fb44b52
rename queries to sub_searches
jdconrad Jun 15, 2023
3e075f4
add additional comment
jdconrad Jun 15, 2023
ce83df4
Merge branch 'main' into rrfmulti
jdconrad Jun 15, 2023
70b5dbd
fix error messages
jdconrad Jun 15, 2023
60f1367
replace more messages with sub searches in place of queries
jdconrad Jun 15, 2023
3a790b4
fix validation test
jdconrad Jun 15, 2023
e6f8591
Update docs/changelog/96224.yaml
jdconrad Jun 15, 2023
f89e085
response to pr comments
jdconrad Jun 15, 2023
7289e37
cleaned up bwc deserialization
jdconrad Jun 16, 2023
48d6f5f
fix change log with highlight
jdconrad Jun 16, 2023
6c991bb
Merge branch 'main' into rrfmulti
jdconrad Jun 16, 2023
f4655c1
Update 96224.yaml
jdconrad Jun 16, 2023
1b98e56
no op
jdconrad Jun 16, 2023
403185f
mute bad test
jdconrad Jun 16, 2023
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/changelog/96224.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pr: 96224
summary: Add multiple queries for ranking to the search endpoint
area: Ranking
type: enhancement
issues: []
highlight:
title: Add multiple queries for ranking to the search endpoint
body: "The search endpoint adds a new top-level element called `sub_searches`. \
This top-level element is a list of searches used for ranking where each \
\"sub search\" is executed independently. The `sub_searches` element is \
used instead of `query` to allow a search using ranking to execute \
multiple queries. The `sub_searches` and `query` elements cannot be used \
together."
notable: true
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ public void testGetTimeSeriesDataStream() {
);
}

@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/96672")
public void testGetTimeSeriesMixedDataStream() {
Instant now = Instant.now().truncatedTo(ChronoUnit.SECONDS);
String dataStream1 = "ds-1";
Expand Down
3 changes: 2 additions & 1 deletion server/src/main/java/org/elasticsearch/TransportVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ private static TransportVersion registerTransportVersion(int id, String uniqueId
public static final TransportVersion V_8_500_010 = registerTransportVersion(8_500_010, "9818C628-1EEC-439B-B943-468F61460675");
public static final TransportVersion V_8_500_011 = registerTransportVersion(8_500_011, "2209F28D-B52E-4BC4-9889-E780F291C32E");
public static final TransportVersion V_8_500_012 = registerTransportVersion(8_500_012, "BB6F4AF1-A860-4FD4-A138-8150FFBE0ABD");
public static final TransportVersion V_8_500_013 = registerTransportVersion(8_500_013, "f65b85ac-db5e-4558-a487-a1dde4f6a33a");

private static class CurrentHolder {
private static final TransportVersion CURRENT = findCurrent(V_8_500_012);
private static final TransportVersion CURRENT = findCurrent(V_8_500_013);

// finds the pluggable current version, or uses the given fallback
private static TransportVersion findCurrent(TransportVersion fallback) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
package org.elasticsearch.action.search;

import org.apache.lucene.search.ScoreDoc;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchPhaseResult;
import org.elasticsearch.search.SearchShardTarget;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.builder.SubSearchSourceBuilder;
import org.elasticsearch.search.dfs.AggregatedDfs;
import org.elasticsearch.search.dfs.DfsKnnResults;
import org.elasticsearch.search.dfs.DfsSearchResult;
Expand Down Expand Up @@ -138,75 +137,23 @@ ShardSearchRequest rewriteShardSearchRequest(ShardSearchRequest request) {
return request;
}

if (source.rankBuilder() == null) {
// this path will use linear combination if there are
// multiple knn queries to combine all knn queries into
// a single query per shard
List<SubSearchSourceBuilder> subSearchSourceBuilders = new ArrayList<>(source.subSearches());

for (DfsKnnResults dfsKnnResults : knnResults) {
List<ScoreDoc> scoreDocs = new ArrayList<>();
for (DfsKnnResults dfsKnnResults : knnResults) {
for (ScoreDoc scoreDoc : dfsKnnResults.scoreDocs()) {
if (scoreDoc.shardIndex == request.shardRequestIndex()) {
scoreDocs.add(scoreDoc);
}
for (ScoreDoc scoreDoc : dfsKnnResults.scoreDocs()) {
if (scoreDoc.shardIndex == request.shardRequestIndex()) {
scoreDocs.add(scoreDoc);
}
}
scoreDocs.sort(Comparator.comparingInt(scoreDoc -> scoreDoc.doc));
// It is possible that the different results refer to the same doc.
for (int i = 0; i < scoreDocs.size() - 1; i++) {
ScoreDoc scoreDoc = scoreDocs.get(i);
int j = i + 1;
for (; j < scoreDocs.size(); j++) {
ScoreDoc otherScoreDoc = scoreDocs.get(j);
if (otherScoreDoc.doc != scoreDoc.doc) {
break;
}
scoreDoc.score += otherScoreDoc.score;
}
if (j > i + 1) {
scoreDocs.subList(i + 1, j).clear();
}
}

KnnScoreDocQueryBuilder knnQuery = new KnnScoreDocQueryBuilder(scoreDocs.toArray(new ScoreDoc[0]));
SearchSourceBuilder newSource = source.shallowCopy().knnSearch(List.of());
if (source.query() == null) {
newSource.query(knnQuery);
} else {
newSource.query(new BoolQueryBuilder().should(knnQuery).should(source.query()));
}
request.source(newSource);
} else {
// this path will keep knn queries separate for ranking per shard
// if there are multiple knn queries

List<QueryBuilder> rankQueryBuilders = new ArrayList<>();
if (source.query() != null) {
rankQueryBuilders.add(source.query());
}

for (DfsKnnResults dfsKnnResults : knnResults) {
List<ScoreDoc> scoreDocs = new ArrayList<>();
for (ScoreDoc scoreDoc : dfsKnnResults.scoreDocs()) {
if (scoreDoc.shardIndex == request.shardRequestIndex()) {
scoreDocs.add(scoreDoc);
}
}
scoreDocs.sort(Comparator.comparingInt(scoreDoc -> scoreDoc.doc));
KnnScoreDocQueryBuilder knnQuery = new KnnScoreDocQueryBuilder(scoreDocs.toArray(new ScoreDoc[0]));
rankQueryBuilders.add(knnQuery);
}

BoolQueryBuilder searchQuery = new BoolQueryBuilder();
for (QueryBuilder queryBuilder : rankQueryBuilders) {
searchQuery.should(queryBuilder);
}

SearchSourceBuilder newSource = source.shallowCopy().query(searchQuery).knnSearch(List.of());
request.source(newSource);
request.rankQueryBuilders(rankQueryBuilders);
subSearchSourceBuilders.add(new SubSearchSourceBuilder(knnQuery));
}

source = source.shallowCopy().subSearches(subSearchSourceBuilders).knnSearch(List.of());
request.source(source);

return request;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ private void innerRun() throws Exception {
final SearchPhaseController.ReducedQueryPhase reducedQueryPhase = resultConsumer.reduce();
// Usually when there is a single shard, we force the search type QUERY_THEN_FETCH. But when there's kNN, we might
// still use DFS_QUERY_THEN_FETCH, which does not perform the "query and fetch" optimization during the query phase.
final boolean queryAndFetchOptimization = queryResults.length() == 1 && context.getRequest().hasKnnSearch() == false;
final boolean queryAndFetchOptimization = queryResults.length() == 1
&& context.getRequest().hasKnnSearch() == false
&& reducedQueryPhase.rankCoordinatorContext() == null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this specifically required by the support for multiple queries or was it missing before as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is specifically required for multiple queries. It wasn't missing before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what confuses me is that we don't look for the multiple queries but rather for the rank coordinator context. This could use a comment to explain why, or maybe the conditional could be shared in a single place, assuming it is always exactly the same.

Copy link
Contributor Author

@jdconrad jdconrad Jun 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: Oops meant this comment for something else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized I didn't answer this correctly. This is required specifically for ranking. If we have a single query and multiple knn searches, those become a boolean query and it's fine to shortcut.

final Runnable finishPhase = () -> moveToNextPhase(
queryResults,
reducedQueryPhase,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ public ActionRequestValidationException validate() {
}
}
if (source != null) {
if (source.subSearches().size() >= 2 && source.rankBuilder() == null) {
validationException = addValidationError("[sub_searches] requires [rank]", validationException);
}
if (source.aggregations() != null) {
validationException = source.aggregations().validate(validationException);
}
Expand All @@ -378,10 +381,10 @@ public ActionRequestValidationException validate() {
validationException
);
}
if (source.knnSearch().isEmpty() || source.query() == null && source.knnSearch().size() < 2) {
int queryCount = source.subSearches().size() + source.knnSearch().size();
if (queryCount < 2) {
validationException = addValidationError(
"[rank] requires a minimum of [2] result sets which"
+ " either needs at minimum [a query and a knn search] or [multiple knn searches]",
"[rank] requires a minimum of [2] result sets using a combination of sub searches and/or knn searches",
validationException
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
import org.elasticsearch.search.builder.PointInTimeBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.builder.SubSearchSourceBuilder;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.fetch.subphase.FieldAndFormat;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
Expand Down Expand Up @@ -165,6 +166,14 @@ public SearchRequestBuilder setQuery(QueryBuilder queryBuilder) {
return this;
}

/**
* Constructs a new search source builder with a list of sub searches.
*/
public SearchRequestBuilder setSubSearches(List<SubSearchSourceBuilder> subSearches) {
sourceBuilder().subSearches(subSearches);
return this;
}

/**
* Sets a filter that will be executed after the query has been executed and only has affect on the search hits
* (not aggregations). This filter is always executed as last filtering mechanism.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ public void sendExecuteQuery(
) {
// we optimize this and expect a QueryFetchSearchResult if we only have a single shard in the search request
// this used to be the QUERY_AND_FETCH which doesn't exist anymore.
final boolean fetchDocuments = request.numberOfShards() == 1;
final boolean fetchDocuments = request.numberOfShards() == 1
&& (request.source() == null || request.source().rankBuilder() == null);
Writeable.Reader<SearchPhaseResult> reader = fetchDocuments ? QueryFetchSearchResult::new : in -> new QuerySearchResult(in, true);

final ActionListener<? super SearchPhaseResult> handler = responseWrapper.apply(connection, listener);
Expand Down
45 changes: 25 additions & 20 deletions server/src/main/java/org/elasticsearch/search/SearchService.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
import org.elasticsearch.search.aggregations.support.AggregationContext;
import org.elasticsearch.search.aggregations.support.AggregationContext.ProductionAggregationContext;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.builder.SubSearchSourceBuilder;
import org.elasticsearch.search.collapse.CollapseContext;
import org.elasticsearch.search.dfs.DfsPhase;
import org.elasticsearch.search.dfs.DfsSearchResult;
Expand Down Expand Up @@ -626,7 +627,7 @@ private SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchSh
} finally {
tracer.stopTrace();
}
if (request.numberOfShards() == 1) {
if (request.numberOfShards() == 1 && (request.source() == null || request.source().rankBuilder() == null)) {
// we already have query results, but we can run fetch at the same time
context.addFetchResult();
return executeFetchPhase(readerContext, context, afterQueryTime);
Expand Down Expand Up @@ -992,13 +993,6 @@ protected SearchContext createContext(
if (context.size() == -1) {
context.size(DEFAULT_SIZE);
}
if (request.rankQueryBuilders().isEmpty() == false) {
List<Query> rankQueries = new ArrayList<>();
for (QueryBuilder queryBuilder : request.rankQueryBuilders()) {
rankQueries.add(queryBuilder.toQuery(context.getSearchExecutionContext()));
}
context.rankShardContext(request.source().rankBuilder().buildRankShardContext(rankQueries, context.from()));
}
context.setTask(task);

context.preProcess();
Expand Down Expand Up @@ -1166,7 +1160,7 @@ private void processFailure(ReaderContext context, Exception exc) {
}
}

private void parseSource(DefaultSearchContext context, SearchSourceBuilder source, boolean includeAggregations) {
private void parseSource(DefaultSearchContext context, SearchSourceBuilder source, boolean includeAggregations) throws IOException {
// nothing to parse...
if (source == null) {
return;
Expand All @@ -1176,9 +1170,10 @@ private void parseSource(DefaultSearchContext context, SearchSourceBuilder sourc
context.from(source.from());
context.size(source.size());
Map<String, InnerHitContextBuilder> innerHitBuilders = new HashMap<>();
if (source.query() != null) {
InnerHitContextBuilder.extractInnerHits(source.query(), innerHitBuilders);
context.parsedQuery(searchExecutionContext.toQuery(source.query()));
QueryBuilder query = source.query();
if (query != null) {
InnerHitContextBuilder.extractInnerHits(query, innerHitBuilders);
context.parsedQuery(searchExecutionContext.toQuery(query));
}
if (source.postFilter() != null) {
InnerHitContextBuilder.extractInnerHits(source.postFilter(), innerHitBuilders);
Expand Down Expand Up @@ -1374,6 +1369,14 @@ private void parseSource(DefaultSearchContext context, SearchSourceBuilder sourc
final CollapseContext collapseContext = source.collapse().build(searchExecutionContext);
context.collapse(collapseContext);
}

if (source.rankBuilder() != null) {
List<Query> queries = new ArrayList<>();
for (SubSearchSourceBuilder subSearchSourceBuilder : source.subSearches()) {
queries.add(subSearchSourceBuilder.toSearchQuery(context.getSearchExecutionContext()));
}
context.rankShardContext(source.rankBuilder().buildRankShardContext(queries, context.from()));
}
}

/**
Expand Down Expand Up @@ -1623,14 +1626,12 @@ private static boolean canMatchAfterRewrite(final ShardSearchRequest request, fi
@SuppressWarnings("unchecked")
public static boolean queryStillMatchesAfterRewrite(ShardSearchRequest request, QueryRewriteContext context) throws IOException {
Rewriteable.rewrite(request.getRewriteable(), context, false);
final boolean aliasFilterCanMatch = request.getAliasFilter().getQueryBuilder() instanceof MatchNoneQueryBuilder == false;
final boolean canMatch;
boolean canMatch = request.getAliasFilter().getQueryBuilder() instanceof MatchNoneQueryBuilder == false;
if (canRewriteToMatchNone(request.source())) {
QueryBuilder queryBuilder = request.source().query();
canMatch = aliasFilterCanMatch && queryBuilder instanceof MatchNoneQueryBuilder == false;
} else {
// null query means match_all
canMatch = aliasFilterCanMatch;
canMatch &= request.source()
.subSearches()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will subsearches here already contain the knn queries too? I think so, and that should not be an issue, but I wanted to double check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there should never be a knn search here because can_match only works with query_then_fetch, but not dfs_query_Then_fetch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh good point. maybe that is something that we need to discuss changing.

.stream()
.anyMatch(sqwb -> sqwb.getQueryBuilder() instanceof MatchNoneQueryBuilder == false);
}
return canMatch;
}
Expand All @@ -1641,7 +1642,11 @@ public static boolean queryStillMatchesAfterRewrite(ShardSearchRequest request,
* a global aggregation is part of this request or if there is a suggest builder present.
*/
public static boolean canRewriteToMatchNone(SearchSourceBuilder source) {
if (source == null || source.query() == null || source.query() instanceof MatchAllQueryBuilder || source.suggest() != null) {
if (source == null || source.suggest() != null) {
return false;
}
if (source.subSearches().isEmpty()
|| source.subSearches().stream().anyMatch(sqwb -> sqwb.getQueryBuilder() instanceof MatchAllQueryBuilder)) {
return false;
}
AggregatorFactories.Builder aggregations = source.aggregations();
Expand Down
Loading