Search in sources :

Example 1 with AliasFilter

use of org.opensearch.search.internal.AliasFilter in project OpenSearch by opensearch-project.

the class TransportSearchAction method executeSearch.

private void executeSearch(SearchTask task, SearchTimeProvider timeProvider, SearchRequest searchRequest, OriginalIndices localIndices, List<SearchShardIterator> remoteShardIterators, BiFunction<String, String, DiscoveryNode> remoteConnections, ClusterState clusterState, Map<String, AliasFilter> remoteAliasMap, ActionListener<SearchResponse> listener, SearchResponse.Clusters clusters, @Nullable SearchContextId searchContext, SearchAsyncActionProvider searchAsyncActionProvider) {
    clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
    // TODO: I think startTime() should become part of ActionRequest and that should be used both for index name
    // date math expressions and $now in scripts. This way all apis will deal with now in the same way instead
    // of just for the _search api
    final List<SearchShardIterator> localShardIterators;
    final Map<String, AliasFilter> aliasFilter;
    final Map<String, Set<String>> indexRoutings;
    final String[] concreteLocalIndices;
    if (searchContext != null) {
        assert searchRequest.pointInTimeBuilder() != null;
        aliasFilter = searchContext.aliasFilter();
        indexRoutings = Collections.emptyMap();
        concreteLocalIndices = localIndices == null ? new String[0] : localIndices.indices();
        localShardIterators = getLocalLocalShardsIteratorFromPointInTime(clusterState, localIndices, searchRequest.getLocalClusterAlias(), searchContext, searchRequest.pointInTimeBuilder().getKeepAlive());
    } else {
        final Index[] indices = resolveLocalIndices(localIndices, clusterState, timeProvider);
        Map<String, Set<String>> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, searchRequest.routing(), searchRequest.indices());
        routingMap = routingMap == null ? Collections.emptyMap() : Collections.unmodifiableMap(routingMap);
        concreteLocalIndices = new String[indices.length];
        for (int i = 0; i < indices.length; i++) {
            concreteLocalIndices[i] = indices[i].getName();
        }
        Map<String, Long> nodeSearchCounts = searchTransportService.getPendingSearchRequests();
        GroupShardsIterator<ShardIterator> localShardRoutings = clusterService.operationRouting().searchShards(clusterState, concreteLocalIndices, routingMap, searchRequest.preference(), searchService.getResponseCollectorService(), nodeSearchCounts);
        localShardIterators = StreamSupport.stream(localShardRoutings.spliterator(), false).map(it -> new SearchShardIterator(searchRequest.getLocalClusterAlias(), it.shardId(), it.getShardRoutings(), localIndices)).collect(Collectors.toList());
        aliasFilter = buildPerIndexAliasFilter(searchRequest, clusterState, indices, remoteAliasMap);
        indexRoutings = routingMap;
    }
    final GroupShardsIterator<SearchShardIterator> shardIterators = mergeShardsIterators(localShardIterators, remoteShardIterators);
    failIfOverShardCountLimit(clusterService, shardIterators.size());
    Map<String, Float> concreteIndexBoosts = resolveIndexBoosts(searchRequest, clusterState);
    // optimize search type for cases where there is only one shard group to search on
    if (shardIterators.size() == 1) {
        // if we only have one group, then we always want Q_T_F, no need for DFS, and no need to do THEN since we hit one shard
        searchRequest.searchType(QUERY_THEN_FETCH);
    }
    if (searchRequest.allowPartialSearchResults() == null) {
        // No user preference defined in search request - apply cluster service default
        searchRequest.allowPartialSearchResults(searchService.defaultAllowPartialSearchResults());
    }
    if (searchRequest.isSuggestOnly()) {
        // disable request cache if we have only suggest
        searchRequest.requestCache(false);
        switch(searchRequest.searchType()) {
            case DFS_QUERY_THEN_FETCH:
                // convert to Q_T_F if we have only suggest
                searchRequest.searchType(QUERY_THEN_FETCH);
                break;
        }
    }
    final DiscoveryNodes nodes = clusterState.nodes();
    BiFunction<String, String, Transport.Connection> connectionLookup = buildConnectionLookup(searchRequest.getLocalClusterAlias(), nodes::get, remoteConnections, searchTransportService::getConnection);
    final Executor asyncSearchExecutor = asyncSearchExecutor(concreteLocalIndices, clusterState);
    final boolean preFilterSearchShards = shouldPreFilterSearchShards(clusterState, searchRequest, concreteLocalIndices, localShardIterators.size() + remoteShardIterators.size());
    searchAsyncActionProvider.asyncSearchAction(task, searchRequest, asyncSearchExecutor, shardIterators, timeProvider, connectionLookup, clusterState, Collections.unmodifiableMap(aliasFilter), concreteIndexBoosts, indexRoutings, listener, preFilterSearchShards, threadPool, clusters).start();
}
Also used : AliasFilter(org.opensearch.search.internal.AliasFilter) Set(java.util.Set) HashSet(java.util.HashSet) Index(org.opensearch.index.Index) Executor(java.util.concurrent.Executor) ShardIterator(org.opensearch.cluster.routing.ShardIterator) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes)

Example 2 with AliasFilter

use of org.opensearch.search.internal.AliasFilter in project OpenSearch by opensearch-project.

the class TransportSearchAction method getRemoteShardsIterator.

static List<SearchShardIterator> getRemoteShardsIterator(Map<String, ClusterSearchShardsResponse> searchShardsResponses, Map<String, OriginalIndices> remoteIndicesByCluster, Map<String, AliasFilter> aliasFilterMap) {
    final List<SearchShardIterator> remoteShardIterators = new ArrayList<>();
    for (Map.Entry<String, ClusterSearchShardsResponse> entry : searchShardsResponses.entrySet()) {
        for (ClusterSearchShardsGroup clusterSearchShardsGroup : entry.getValue().getGroups()) {
            // add the cluster name to the remote index names for indices disambiguation
            // this ends up in the hits returned with the search response
            ShardId shardId = clusterSearchShardsGroup.getShardId();
            AliasFilter aliasFilter = aliasFilterMap.get(shardId.getIndex().getUUID());
            String[] aliases = aliasFilter.getAliases();
            String clusterAlias = entry.getKey();
            String[] finalIndices = aliases.length == 0 ? new String[] { shardId.getIndexName() } : aliases;
            final OriginalIndices originalIndices = remoteIndicesByCluster.get(clusterAlias);
            assert originalIndices != null : "original indices are null for clusterAlias: " + clusterAlias;
            SearchShardIterator shardIterator = new SearchShardIterator(clusterAlias, shardId, Arrays.asList(clusterSearchShardsGroup.getShards()), new OriginalIndices(finalIndices, originalIndices.indicesOptions()));
            remoteShardIterators.add(shardIterator);
        }
    }
    return remoteShardIterators;
}
Also used : ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) ShardId(org.opensearch.index.shard.ShardId) AliasFilter(org.opensearch.search.internal.AliasFilter) ArrayList(java.util.ArrayList) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup) OriginalIndices(org.opensearch.action.OriginalIndices)

Example 3 with AliasFilter

use of org.opensearch.search.internal.AliasFilter in project OpenSearch by opensearch-project.

the class TransportSearchAction method getRemoteAliasFilters.

static Map<String, AliasFilter> getRemoteAliasFilters(Map<String, ClusterSearchShardsResponse> searchShardsResp) {
    final Map<String, AliasFilter> aliasFilterMap = new HashMap<>();
    for (Map.Entry<String, ClusterSearchShardsResponse> entry : searchShardsResp.entrySet()) {
        ClusterSearchShardsResponse searchShardsResponse = entry.getValue();
        final Map<String, AliasFilter> indicesAndFilters = searchShardsResponse.getIndicesAndFilters();
        for (ClusterSearchShardsGroup clusterSearchShardsGroup : searchShardsResponse.getGroups()) {
            ShardId shardId = clusterSearchShardsGroup.getShardId();
            final AliasFilter aliasFilter;
            if (indicesAndFilters == null) {
                aliasFilter = AliasFilter.EMPTY;
            } else {
                aliasFilter = indicesAndFilters.get(shardId.getIndexName());
                assert aliasFilter != null : "alias filter must not be null for index: " + shardId.getIndex();
            }
            // here we have to map the filters to the UUID since from now on we use the uuid for the lookup
            aliasFilterMap.put(shardId.getIndex().getUUID(), aliasFilter);
        }
    }
    return aliasFilterMap;
}
Also used : ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) ShardId(org.opensearch.index.shard.ShardId) AliasFilter(org.opensearch.search.internal.AliasFilter) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup)

Example 4 with AliasFilter

use of org.opensearch.search.internal.AliasFilter in project OpenSearch by opensearch-project.

the class TransportSearchAction method buildPerIndexAliasFilter.

private Map<String, AliasFilter> buildPerIndexAliasFilter(SearchRequest request, ClusterState clusterState, Index[] concreteIndices, Map<String, AliasFilter> remoteAliasMap) {
    final Map<String, AliasFilter> aliasFilterMap = new HashMap<>();
    final Set<String> indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, request.indices());
    for (Index index : concreteIndices) {
        clusterState.blocks().indexBlockedRaiseException(ClusterBlockLevel.READ, index.getName());
        AliasFilter aliasFilter = searchService.buildAliasFilter(clusterState, index.getName(), indicesAndAliases);
        assert aliasFilter != null;
        aliasFilterMap.put(index.getUUID(), aliasFilter);
    }
    aliasFilterMap.putAll(remoteAliasMap);
    return aliasFilterMap;
}
Also used : AliasFilter(org.opensearch.search.internal.AliasFilter) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Index(org.opensearch.index.Index)

Example 5 with AliasFilter

use of org.opensearch.search.internal.AliasFilter in project OpenSearch by opensearch-project.

the class TransportExplainAction method resolveRequest.

@Override
protected void resolveRequest(ClusterState state, InternalRequest request) {
    final Set<String> indicesAndAliases = indexNameExpressionResolver.resolveExpressions(state, request.request().index());
    final AliasFilter aliasFilter = searchService.buildAliasFilter(state, request.concreteIndex(), indicesAndAliases);
    request.request().filteringAlias(aliasFilter);
    // Fail fast on the node that received the request.
    if (request.request().routing() == null && state.getMetadata().routingRequired(request.concreteIndex())) {
        throw new RoutingMissingException(request.concreteIndex(), request.request().id());
    }
}
Also used : AliasFilter(org.opensearch.search.internal.AliasFilter) RoutingMissingException(org.opensearch.action.RoutingMissingException)

Aggregations

AliasFilter (org.opensearch.search.internal.AliasFilter)39 ShardId (org.opensearch.index.shard.ShardId)21 ShardSearchRequest (org.opensearch.search.internal.ShardSearchRequest)19 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)17 CountDownLatch (java.util.concurrent.CountDownLatch)16 OriginalIndices (org.opensearch.action.OriginalIndices)16 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)15 HashMap (java.util.HashMap)14 SearchShardTarget (org.opensearch.search.SearchShardTarget)11 SearchSourceBuilder (org.opensearch.search.builder.SearchSourceBuilder)11 IOException (java.io.IOException)10 ArrayList (java.util.ArrayList)10 HashSet (java.util.HashSet)10 SearchRequest (org.opensearch.action.search.SearchRequest)10 IndexService (org.opensearch.index.IndexService)10 IndexShard (org.opensearch.index.shard.IndexShard)10 ShardSearchContextId (org.opensearch.search.internal.ShardSearchContextId)10 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)9 AtomicReference (java.util.concurrent.atomic.AtomicReference)9 IndicesService (org.opensearch.indices.IndicesService)9