Skip to content

Commit e2a593b

Browse files
committed
Do not search locally if remote index pattern resolves to no indices (#25436)
This commit changes how we determine if there were any remote indices that a search should have been executed against. Previously, we used the list of remote shard iterators but if the remote index pattern resolved to no indices there would be no remote shard iterators even though the request specified remote indices. The map of remote cluster names to the original indices is used instead so that we can determine if there were remote indices even when there are no remote shard iterators. Closes #25426
1 parent a0bbb2a commit e2a593b

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.elasticsearch.cluster.routing.GroupShardsIterator;
3434
import org.elasticsearch.cluster.routing.ShardIterator;
3535
import org.elasticsearch.cluster.service.ClusterService;
36-
import org.elasticsearch.common.Strings;
3736
import org.elasticsearch.common.inject.Inject;
3837
import org.elasticsearch.common.settings.Setting;
3938
import org.elasticsearch.common.settings.Setting.Property;
@@ -184,7 +183,7 @@ protected void doExecute(Task task, SearchRequest searchRequest, ActionListener<
184183
searchRequest.indices(), idx -> indexNameExpressionResolver.hasIndexOrAlias(idx, clusterState));
185184
OriginalIndices localIndices = remoteClusterIndices.remove(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY);
186185
if (remoteClusterIndices.isEmpty()) {
187-
executeSearch((SearchTask)task, timeProvider, searchRequest, localIndices, Collections.emptyList(),
186+
executeSearch((SearchTask)task, timeProvider, searchRequest, localIndices, remoteClusterIndices, Collections.emptyList(),
188187
(clusterName, nodeId) -> null, clusterState, Collections.emptyMap(), listener);
189188
} else {
190189
remoteClusterService.collectSearchShards(searchRequest.indicesOptions(), searchRequest.preference(), searchRequest.routing(),
@@ -193,7 +192,7 @@ protected void doExecute(Task task, SearchRequest searchRequest, ActionListener<
193192
Map<String, AliasFilter> remoteAliasFilters = new HashMap<>();
194193
BiFunction<String, String, DiscoveryNode> clusterNodeLookup = processRemoteShards(searchShardsResponses,
195194
remoteClusterIndices, remoteShardIterators, remoteAliasFilters);
196-
executeSearch((SearchTask)task, timeProvider, searchRequest, localIndices, remoteShardIterators,
195+
executeSearch((SearchTask) task, timeProvider, searchRequest, localIndices, remoteClusterIndices, remoteShardIterators,
197196
clusterNodeLookup, clusterState, remoteAliasFilters, listener);
198197
}, listener::onFailure));
199198
}
@@ -249,16 +248,16 @@ static BiFunction<String, String, DiscoveryNode> processRemoteShards(Map<String,
249248
}
250249

251250
private void executeSearch(SearchTask task, SearchTimeProvider timeProvider, SearchRequest searchRequest, OriginalIndices localIndices,
252-
List<SearchShardIterator> remoteShardIterators, BiFunction<String, String, DiscoveryNode> remoteConnections,
253-
ClusterState clusterState, Map<String, AliasFilter> remoteAliasMap,
254-
ActionListener<SearchResponse> listener) {
251+
Map<String, OriginalIndices> remoteClusterIndices, List<SearchShardIterator> remoteShardIterators,
252+
BiFunction<String, String, DiscoveryNode> remoteConnections, ClusterState clusterState,
253+
Map<String, AliasFilter> remoteAliasMap, ActionListener<SearchResponse> listener) {
255254

256255
clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
257256
// TODO: I think startTime() should become part of ActionRequest and that should be used both for index name
258257
// date math expressions and $now in scripts. This way all apis will deal with now in the same way instead
259258
// of just for the _search api
260259
final Index[] indices;
261-
if (localIndices.indices().length == 0 && remoteShardIterators.size() > 0) {
260+
if (localIndices.indices().length == 0 && remoteClusterIndices.isEmpty() == false) {
262261
indices = Index.EMPTY_ARRAY; // don't search on _all if only remote indices were specified
263262
} else {
264263
indices = indexNameExpressionResolver.concreteIndices(clusterState, searchRequest.indicesOptions(),
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
"Search with missing remote index pattern":
3+
- do:
4+
catch: "request"
5+
search:
6+
index: "my_remote_cluster:foo"
7+
8+
- do:
9+
search:
10+
index: "my_remote_cluster:fooo*"
11+
- match: { _shards.total: 0 }
12+
- match: { hits.total: 0 }
13+
14+
- do:
15+
search:
16+
index: "*:foo*"
17+
18+
- match: { _shards.total: 0 }
19+
- match: { hits.total: 0 }
20+
21+
- do:
22+
search:
23+
index: "my_remote_cluster:test_index,my_remote_cluster:foo*"
24+
body:
25+
aggs:
26+
cluster:
27+
terms:
28+
field: f1.keyword
29+
30+
- match: { _shards.total: 3 }
31+
- match: { hits.total: 6 }
32+
- length: { aggregations.cluster.buckets: 1 }
33+
- match: { aggregations.cluster.buckets.0.key: "remote_cluster" }
34+
- match: { aggregations.cluster.buckets.0.doc_count: 6 }
35+
36+
- do:
37+
catch: "request"
38+
search:
39+
index: "my_remote_cluster:test_index,my_remote_cluster:foo"
40+
body:
41+
aggs:
42+
cluster:
43+
terms:
44+
field: f1.keyword

0 commit comments

Comments
 (0)