Skip to content

Commit 447bce4

Browse files
authored
Semantic Search CCS Support - Add Prerequisite Info to Query Rewrite Context (#134327)
1 parent c195fa9 commit 447bce4

File tree

19 files changed

+252
-20
lines changed

19 files changed

+252
-20
lines changed

server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,18 @@ protected void doExecute(Task task, ValidateQueryRequest request, ActionListener
128128
if (request.query() == null) {
129129
rewriteListener.onResponse(request.query());
130130
} else {
131+
// We can safely set the cluster alias and CCS minimize round-trips to null because the validate endpoint can only reference
132+
// local indices
131133
Rewriteable.rewriteAndFetch(
132134
request.query(),
133-
searchService.getRewriteContext(timeProvider, resolvedIndices, null),
135+
searchService.getRewriteContext(
136+
timeProvider,
137+
clusterService.state().getMinTransportVersion(),
138+
null,
139+
resolvedIndices,
140+
null,
141+
null
142+
),
134143
rewriteListener
135144
);
136145
}

server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,24 @@ protected void doExecute(Task task, ExplainRequest request, ActionListener<Expla
101101
super.doExecute(task, request, l);
102102
});
103103

104+
// Set cluster alias to null because this request targets a single shard and thus there cannot be any multi-cluster resource
105+
// conflicts. This is also consistent with the cluster alias value set downstream in the SearchExecutionContext used in this
106+
// code path.
107+
// Set CCS minimize round-trips to false because this transport implementation runs coordinator rewrite only on the local cluster.
104108
assert request.query() != null;
105109
LongSupplier timeProvider = () -> request.nowInMillis;
106-
Rewriteable.rewriteAndFetch(request.query(), searchService.getRewriteContext(timeProvider, resolvedIndices, null), rewriteListener);
110+
Rewriteable.rewriteAndFetch(
111+
request.query(),
112+
searchService.getRewriteContext(
113+
timeProvider,
114+
clusterService.state().getMinTransportVersion(),
115+
null,
116+
resolvedIndices,
117+
null,
118+
false
119+
),
120+
rewriteListener
121+
);
107122
}
108123

109124
@Override

server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,11 @@ public void onFailure(Exception e) {
550550
original,
551551
searchService.getRewriteContext(
552552
timeProvider::absoluteStartMillis,
553+
clusterState.getMinTransportVersion(),
554+
original.getLocalClusterAlias(),
553555
resolvedIndices,
554556
original.pointInTimeBuilder(),
557+
shouldMinimizeRoundtrips(original),
555558
isExplain
556559
),
557560
rewriteListener

server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.elasticsearch.action.ResolvedIndices;
1717
import org.elasticsearch.action.support.ActionFilters;
1818
import org.elasticsearch.action.support.HandledTransportAction;
19+
import org.elasticsearch.cluster.ClusterState;
1920
import org.elasticsearch.cluster.ProjectState;
2021
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
2122
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
@@ -113,7 +114,8 @@ public void searchShards(Task task, SearchShardsRequest searchShardsRequest, Act
113114
System::nanoTime
114115
);
115116

116-
final ProjectState project = projectResolver.getProjectState(clusterService.state());
117+
final ClusterState clusterState = clusterService.state();
118+
final ProjectState project = projectResolver.getProjectState(clusterState);
117119
final ResolvedIndices resolvedIndices = ResolvedIndices.resolveWithIndicesRequest(
118120
searchShardsRequest,
119121
project.metadata(),
@@ -125,9 +127,17 @@ public void searchShards(Task task, SearchShardsRequest searchShardsRequest, Act
125127
throw new UnsupportedOperationException("search_shards API doesn't support remote indices " + searchShardsRequest);
126128
}
127129

130+
// Set CCS minimize round-trips to null since search shards requests are guaranteed to only reference local indices
128131
Rewriteable.rewriteAndFetch(
129132
original,
130-
searchService.getRewriteContext(timeProvider::absoluteStartMillis, resolvedIndices, null),
133+
searchService.getRewriteContext(
134+
timeProvider::absoluteStartMillis,
135+
clusterState.getMinTransportVersion(),
136+
searchShardsRequest.clusterAlias(),
137+
resolvedIndices,
138+
null,
139+
null
140+
),
131141
listener.delegateFailureAndWrap((delegate, searchRequest) -> {
132142
Index[] concreteIndices = resolvedIndices.getConcreteLocalIndices();
133143
final Set<ResolvedExpression> indicesAndAliases = indexNameExpressionResolver.resolveExpressions(

server/src/main/java/org/elasticsearch/index/IndexService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,8 @@ public QueryRewriteContext newQueryRewriteContext(
824824
mappingLookup,
825825
parseRuntimeMappings(runtimeMappings, mapperService, indexSettings, mappingLookup),
826826
indexSettings,
827+
null,
828+
clusterAlias,
827829
new Index(
828830
RemoteClusterAware.buildRemoteIndexName(clusterAlias, indexSettings.getIndex().getName()),
829831
indexSettings.getIndex().getUUID()
@@ -836,6 +838,7 @@ public QueryRewriteContext newQueryRewriteContext(
836838
null,
837839
null,
838840
null,
841+
null,
839842
false
840843
);
841844
}

server/src/main/java/org/elasticsearch/index/query/CoordinatorRewriteContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ public CoordinatorRewriteContext(
120120
null,
121121
null,
122122
null,
123+
null,
124+
null,
125+
null,
123126
false
124127
);
125128
this.dateFieldRangeInfo = dateFieldRangeInfo;

server/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
package org.elasticsearch.index.query;
1010

11+
import org.elasticsearch.TransportVersion;
1112
import org.elasticsearch.action.ActionListener;
1213
import org.elasticsearch.action.ResolvedIndices;
1314
import org.elasticsearch.client.internal.Client;
@@ -32,6 +33,7 @@
3233
import org.elasticsearch.script.ScriptCompiler;
3334
import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
3435
import org.elasticsearch.search.builder.PointInTimeBuilder;
36+
import org.elasticsearch.transport.RemoteClusterAware;
3537
import org.elasticsearch.xcontent.XContentParser;
3638
import org.elasticsearch.xcontent.XContentParserConfiguration;
3739

@@ -56,6 +58,8 @@ public class QueryRewriteContext {
5658
protected final MappingLookup mappingLookup;
5759
protected final Map<String, MappedFieldType> runtimeMappings;
5860
protected final IndexSettings indexSettings;
61+
private final TransportVersion minTransportVersion;
62+
private final String localClusterAlias;
5963
protected final Index fullyQualifiedIndex;
6064
protected final Predicate<String> indexNameMatcher;
6165
protected final NamedWriteableRegistry writeableRegistry;
@@ -72,6 +76,7 @@ public class QueryRewriteContext {
7276
private final ResolvedIndices resolvedIndices;
7377
private final PointInTimeBuilder pit;
7478
private QueryRewriteInterceptor queryRewriteInterceptor;
79+
private final Boolean ccsMinimizeRoundTrips;
7580
private final boolean isExplain;
7681

7782
public QueryRewriteContext(
@@ -82,6 +87,8 @@ public QueryRewriteContext(
8287
final MappingLookup mappingLookup,
8388
final Map<String, MappedFieldType> runtimeMappings,
8489
final IndexSettings indexSettings,
90+
final TransportVersion minTransportVersion,
91+
final String localClusterAlias,
8592
final Index fullyQualifiedIndex,
8693
final Predicate<String> indexNameMatcher,
8794
final NamedWriteableRegistry namedWriteableRegistry,
@@ -91,6 +98,7 @@ public QueryRewriteContext(
9198
final ResolvedIndices resolvedIndices,
9299
final PointInTimeBuilder pit,
93100
final QueryRewriteInterceptor queryRewriteInterceptor,
101+
final Boolean ccsMinimizeRoundTrips,
94102
final boolean isExplain
95103
) {
96104

@@ -102,6 +110,8 @@ public QueryRewriteContext(
102110
this.allowUnmappedFields = indexSettings == null || indexSettings.isDefaultAllowUnmappedFields();
103111
this.runtimeMappings = runtimeMappings;
104112
this.indexSettings = indexSettings;
113+
this.minTransportVersion = minTransportVersion;
114+
this.localClusterAlias = localClusterAlias;
105115
this.fullyQualifiedIndex = fullyQualifiedIndex;
106116
this.indexNameMatcher = indexNameMatcher;
107117
this.writeableRegistry = namedWriteableRegistry;
@@ -111,6 +121,7 @@ public QueryRewriteContext(
111121
this.resolvedIndices = resolvedIndices;
112122
this.pit = pit;
113123
this.queryRewriteInterceptor = queryRewriteInterceptor;
124+
this.ccsMinimizeRoundTrips = ccsMinimizeRoundTrips;
114125
this.isExplain = isExplain;
115126
}
116127

@@ -132,6 +143,9 @@ public QueryRewriteContext(final XContentParserConfiguration parserConfiguration
132143
null,
133144
null,
134145
null,
146+
null,
147+
null,
148+
null,
135149
false
136150
);
137151
}
@@ -140,20 +154,37 @@ public QueryRewriteContext(
140154
final XContentParserConfiguration parserConfiguration,
141155
final Client client,
142156
final LongSupplier nowInMillis,
157+
final TransportVersion minTransportVersion,
158+
final String localClusterAlias,
143159
final ResolvedIndices resolvedIndices,
144160
final PointInTimeBuilder pit,
145-
final QueryRewriteInterceptor queryRewriteInterceptor
161+
final QueryRewriteInterceptor queryRewriteInterceptor,
162+
final Boolean ccsMinimizeRoundTrips
146163
) {
147-
this(parserConfiguration, client, nowInMillis, resolvedIndices, pit, queryRewriteInterceptor, false);
164+
this(
165+
parserConfiguration,
166+
client,
167+
nowInMillis,
168+
minTransportVersion,
169+
localClusterAlias,
170+
resolvedIndices,
171+
pit,
172+
queryRewriteInterceptor,
173+
ccsMinimizeRoundTrips,
174+
false
175+
);
148176
}
149177

150178
public QueryRewriteContext(
151179
final XContentParserConfiguration parserConfiguration,
152180
final Client client,
153181
final LongSupplier nowInMillis,
182+
final TransportVersion minTransportVersion,
183+
final String localClusterAlias,
154184
final ResolvedIndices resolvedIndices,
155185
final PointInTimeBuilder pit,
156186
final QueryRewriteInterceptor queryRewriteInterceptor,
187+
final Boolean ccsMinimizeRoundTrips,
157188
final boolean isExplain
158189
) {
159190
this(
@@ -164,6 +195,8 @@ public QueryRewriteContext(
164195
MappingLookup.EMPTY,
165196
Collections.emptyMap(),
166197
null,
198+
minTransportVersion,
199+
localClusterAlias,
167200
null,
168201
null,
169202
null,
@@ -173,6 +206,7 @@ public QueryRewriteContext(
173206
resolvedIndices,
174207
pit,
175208
queryRewriteInterceptor,
209+
ccsMinimizeRoundTrips,
176210
isExplain
177211
);
178212
}
@@ -279,6 +313,13 @@ public void setMapUnmappedFieldAsString(boolean mapUnmappedFieldAsString) {
279313
this.mapUnmappedFieldAsString = mapUnmappedFieldAsString;
280314
}
281315

316+
/**
317+
* Returns the CCS minimize round-trips setting. Returns null if the value of the setting is unknown.
318+
*/
319+
public Boolean isCcsMinimizeRoundTrips() {
320+
return ccsMinimizeRoundTrips;
321+
}
322+
282323
public boolean isExplain() {
283324
return this.isExplain;
284325
}
@@ -345,6 +386,20 @@ public void onFailure(Exception e) {
345386
}
346387
}
347388

389+
/**
390+
* Returns the local cluster alias.
391+
*/
392+
public String getLocalClusterAlias() {
393+
return localClusterAlias != null ? localClusterAlias : RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY;
394+
}
395+
396+
/**
397+
* Returns the minimum {@link TransportVersion} for intra-cluster node-to-node communications. Returns null if it is unknown.
398+
*/
399+
public TransportVersion getMinTransportVersion() {
400+
return minTransportVersion;
401+
}
402+
348403
/**
349404
* Returns the fully qualified index including a remote cluster alias if applicable, and the index uuid
350405
*/

server/src/main/java/org/elasticsearch/index/query/SearchExecutionContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ public SearchExecutionContext(
198198
searcher,
199199
nowInMillis,
200200
indexNameMatcher,
201+
clusterAlias,
201202
new Index(
202203
RemoteClusterAware.buildRemoteIndexName(clusterAlias, indexSettings.getIndex().getName()),
203204
indexSettings.getIndex().getUUID()
@@ -227,6 +228,7 @@ public SearchExecutionContext(SearchExecutionContext source) {
227228
source.searcher,
228229
source.nowInMillis,
229230
source.indexNameMatcher,
231+
source.getLocalClusterAlias(),
230232
source.getFullyQualifiedIndex(),
231233
source.allowExpensiveQueries,
232234
source.getValuesSourceRegistry(),
@@ -252,6 +254,7 @@ private SearchExecutionContext(
252254
IndexSearcher searcher,
253255
LongSupplier nowInMillis,
254256
Predicate<String> indexNameMatcher,
257+
String clusterAlias,
255258
Index fullyQualifiedIndex,
256259
BooleanSupplier allowExpensiveQueries,
257260
ValuesSourceRegistry valuesSourceRegistry,
@@ -267,6 +270,8 @@ private SearchExecutionContext(
267270
mappingLookup,
268271
runtimeMappings,
269272
indexSettings,
273+
null,
274+
clusterAlias,
270275
fullyQualifiedIndex,
271276
indexNameMatcher,
272277
namedWriteableRegistry,
@@ -276,6 +281,7 @@ private SearchExecutionContext(
276281
null,
277282
null,
278283
null,
284+
null,
279285
false
280286
);
281287
this.shardId = shardId;

server/src/main/java/org/elasticsearch/indices/IndicesService.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.apache.lucene.util.RamUsageEstimator;
1919
import org.elasticsearch.ElasticsearchException;
2020
import org.elasticsearch.ResourceAlreadyExistsException;
21+
import org.elasticsearch.TransportVersion;
2122
import org.elasticsearch.action.ActionListener;
2223
import org.elasticsearch.action.ActionRunnable;
2324
import org.elasticsearch.action.ResolvedIndices;
@@ -1847,11 +1848,25 @@ public AliasFilter buildAliasFilter(ProjectState project, String index, Set<Reso
18471848
*/
18481849
public QueryRewriteContext getRewriteContext(
18491850
LongSupplier nowInMillis,
1851+
TransportVersion minTransportVersion,
1852+
String clusterAlias,
18501853
ResolvedIndices resolvedIndices,
18511854
PointInTimeBuilder pit,
1855+
final Boolean ccsMinimizeRoundTrips,
18521856
final boolean isExplain
18531857
) {
1854-
return new QueryRewriteContext(parserConfig, client, nowInMillis, resolvedIndices, pit, queryRewriteInterceptor, isExplain);
1858+
return new QueryRewriteContext(
1859+
parserConfig,
1860+
client,
1861+
nowInMillis,
1862+
minTransportVersion,
1863+
clusterAlias,
1864+
resolvedIndices,
1865+
pit,
1866+
queryRewriteInterceptor,
1867+
ccsMinimizeRoundTrips,
1868+
isExplain
1869+
);
18551870
}
18561871

18571872
public DataRewriteContext getDataRewriteContext(LongSupplier nowInMillis) {

0 commit comments

Comments
 (0)