diff --git a/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java b/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java index e09554d0ec3e3..33092c63f1ab7 100644 --- a/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java +++ b/server/src/main/java/org/elasticsearch/action/get/TransportMultiGetAction.java @@ -21,6 +21,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.util.concurrent.AtomicArray; import org.elasticsearch.common.util.concurrent.EsExecutors; +import org.elasticsearch.core.Tuple; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.indices.IndicesService; import org.elasticsearch.tasks.Task; @@ -60,16 +61,24 @@ protected void doExecute(Task task, final MultiGetRequest request, final ActionL final AtomicArray responses = new AtomicArray<>(request.items.size()); final Map shardRequests = new HashMap<>(); + // single item cache that maps the provided index name to the resolved one + Tuple lastResolvedIndex = Tuple.tuple(null, null); for (int i = 0; i < request.items.size(); i++) { MultiGetRequest.Item item = request.items.get(i); ShardId shardId; try { - String concreteSingleIndex = indexNameExpressionResolver.concreteSingleIndex(clusterState, item).getName(); + String concreteSingleIndex; + if (item.index().equals(lastResolvedIndex.v1())) { + concreteSingleIndex = lastResolvedIndex.v2(); + } else { + concreteSingleIndex = indexNameExpressionResolver.concreteSingleIndex(clusterState, item).getName(); + lastResolvedIndex = Tuple.tuple(item.index(), concreteSingleIndex); + } item.routing(clusterState.metadata().resolveIndexRouting(item.routing(), item.index())); shardId = clusterService.operationRouting() - .getShards(clusterState, concreteSingleIndex, item.id(), item.routing(), null) + .getIndexShardRoutingTable(clusterState, concreteSingleIndex, item.id(), item.routing()) .shardId(); } catch (RoutingMissingException e) { responses.set(i, newItemFailure(e.getIndex().getName(), e.getId(), e)); diff --git a/server/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java b/server/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java index 3128404276dfb..79311e46504b2 100644 --- a/server/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java +++ b/server/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java @@ -56,6 +56,16 @@ void setUseAdaptiveReplicaSelection(boolean useAdaptiveReplicaSelection) { this.useAdaptiveReplicaSelection = useAdaptiveReplicaSelection; } + public IndexShardRoutingTable getIndexShardRoutingTable( + ClusterState clusterState, + String index, + String id, + @Nullable String routing + ) { + IndexRouting indexRouting = IndexRouting.fromIndexMetadata(indexMetadata(clusterState, index)); + return clusterState.getRoutingTable().shardRoutingTable(index, indexRouting.getShard(id, routing)); + } + /** * Shards to use for a {@code GET} operation. * @return A shard iterator that can be used for GETs, or null if e.g. due to preferences no match is found. @@ -67,8 +77,7 @@ public ShardIterator getShards( @Nullable String routing, @Nullable String preference ) { - IndexRouting indexRouting = IndexRouting.fromIndexMetadata(indexMetadata(clusterState, index)); - IndexShardRoutingTable shards = clusterState.getRoutingTable().shardRoutingTable(index, indexRouting.getShard(id, routing)); + IndexShardRoutingTable shards = getIndexShardRoutingTable(clusterState, index, id, routing); return preferenceActiveShardIterator(shards, clusterState.nodes().getLocalNodeId(), clusterState.nodes(), preference, null, null); }