presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/client/ElasticsearchClient.java/ElasticsearchClient/getSearchShards
class ElasticsearchClient:    public List<Shard> getSearchShards(String index)
    {
        Map<String, ElasticsearchNode> nodeById = getNodes().stream()
                .collect(toImmutableMap(ElasticsearchNode::getId, Function.identity()));

        SearchShardsResponse shardsResponse = doRequest(format("/%s/_search_shards", index), SEARCH_SHARDS_RESPONSE_CODEC::fromJson);

        ImmutableList.Builder<Shard> shards = ImmutableList.builder();
        List<ElasticsearchNode> nodes = ImmutableList.copyOf(nodeById.values());

        for (List<SearchShardsResponse.Shard> shardGroup : shardsResponse.getShardGroups()) {
            Optional<SearchShardsResponse.Shard> candidate = shardGroup.stream()
                    .filter(shard -> shard.getNode() != null && nodeById.containsKey(shard.getNode()))
                    .min(this::shardPreference);

            SearchShardsResponse.Shard chosen;
            ElasticsearchNode node;
            if (!candidate.isPresent()) {
                // pick an arbitrary shard with and assign to an arbitrary node
                chosen = shardGroup.stream()
                        .min(this::shardPreference)
                        .get();
                node = nodes.get(chosen.getShard() % nodes.size());
            }
            else {
                chosen = candidate.get();
                node = nodeById.get(chosen.getNode());
            }

            shards.add(new Shard(chosen.getShard(), node.getAddress()));
        }

        return shards.build();
    }