Search in sources :

Example 1 with InternalSearchResponse

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

the class MultiSearchTemplateResponseTests method createTestInstance.

@Override
protected MultiSearchTemplateResponse createTestInstance() {
    int numItems = randomIntBetween(0, 128);
    long overallTookInMillis = randomNonNegativeLong();
    MultiSearchTemplateResponse.Item[] items = new MultiSearchTemplateResponse.Item[numItems];
    for (int i = 0; i < numItems; i++) {
        // Creating a minimal response is OK, because SearchResponse self
        // is tested elsewhere.
        long tookInMillis = randomNonNegativeLong();
        int totalShards = randomIntBetween(1, Integer.MAX_VALUE);
        int successfulShards = randomIntBetween(0, totalShards);
        int skippedShards = totalShards - successfulShards;
        InternalSearchResponse internalSearchResponse = InternalSearchResponse.empty();
        SearchResponse.Clusters clusters = randomClusters();
        SearchTemplateResponse searchTemplateResponse = new SearchTemplateResponse();
        SearchResponse searchResponse = new SearchResponse(internalSearchResponse, null, totalShards, successfulShards, skippedShards, tookInMillis, ShardSearchFailure.EMPTY_ARRAY, clusters);
        searchTemplateResponse.setResponse(searchResponse);
        items[i] = new MultiSearchTemplateResponse.Item(searchTemplateResponse, null);
    }
    return new MultiSearchTemplateResponse(items, overallTookInMillis);
}
Also used : InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) SearchResponse(org.opensearch.action.search.SearchResponse)

Example 2 with InternalSearchResponse

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

the class SearchResponseMerger method getMergedResponse.

/**
 * Returns the merged response. To be called once all responses have been added through {@link #add(SearchResponse)}
 * so that all responses are merged into a single one.
 */
SearchResponse getMergedResponse(SearchResponse.Clusters clusters) {
    // we end up calling merge without anything to merge, we just return an empty search response
    if (searchResponses.size() == 0) {
        return SearchResponse.empty(searchTimeProvider::buildTookInMillis, clusters);
    }
    int totalShards = 0;
    int skippedShards = 0;
    int successfulShards = 0;
    // the current reduce phase counts as one
    int numReducePhases = 1;
    List<ShardSearchFailure> failures = new ArrayList<>();
    Map<String, ProfileShardResult> profileResults = new HashMap<>();
    List<InternalAggregations> aggs = new ArrayList<>();
    Map<ShardIdAndClusterAlias, Integer> shards = new TreeMap<>();
    List<TopDocs> topDocsList = new ArrayList<>(searchResponses.size());
    Map<String, List<Suggest.Suggestion>> groupedSuggestions = new HashMap<>();
    Boolean trackTotalHits = null;
    SearchPhaseController.TopDocsStats topDocsStats = new SearchPhaseController.TopDocsStats(trackTotalHitsUpTo);
    for (SearchResponse searchResponse : searchResponses) {
        totalShards += searchResponse.getTotalShards();
        skippedShards += searchResponse.getSkippedShards();
        successfulShards += searchResponse.getSuccessfulShards();
        numReducePhases += searchResponse.getNumReducePhases();
        Collections.addAll(failures, searchResponse.getShardFailures());
        profileResults.putAll(searchResponse.getProfileResults());
        if (searchResponse.getAggregations() != null) {
            InternalAggregations internalAggs = (InternalAggregations) searchResponse.getAggregations();
            aggs.add(internalAggs);
        }
        Suggest suggest = searchResponse.getSuggest();
        if (suggest != null) {
            for (Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> entries : suggest) {
                List<Suggest.Suggestion> suggestionList = groupedSuggestions.computeIfAbsent(entries.getName(), s -> new ArrayList<>());
                suggestionList.add(entries);
            }
            List<CompletionSuggestion> completionSuggestions = suggest.filter(CompletionSuggestion.class);
            for (CompletionSuggestion completionSuggestion : completionSuggestions) {
                for (CompletionSuggestion.Entry options : completionSuggestion) {
                    for (CompletionSuggestion.Entry.Option option : options) {
                        SearchShardTarget shard = option.getHit().getShard();
                        ShardIdAndClusterAlias shardId = new ShardIdAndClusterAlias(shard.getShardId(), shard.getClusterAlias());
                        shards.putIfAbsent(shardId, null);
                    }
                }
            }
        }
        SearchHits searchHits = searchResponse.getHits();
        final TotalHits totalHits;
        if (searchHits.getTotalHits() == null) {
            // in case we didn't track total hits, we get null from each cluster, but we need to set 0 eq to the TopDocs
            totalHits = new TotalHits(0, TotalHits.Relation.EQUAL_TO);
            assert trackTotalHits == null || trackTotalHits == false;
            trackTotalHits = false;
        } else {
            totalHits = searchHits.getTotalHits();
            assert trackTotalHits == null || trackTotalHits;
            trackTotalHits = true;
        }
        TopDocs topDocs = searchHitsToTopDocs(searchHits, totalHits, shards);
        topDocsStats.add(new TopDocsAndMaxScore(topDocs, searchHits.getMaxScore()), searchResponse.isTimedOut(), searchResponse.isTerminatedEarly());
        if (searchHits.getHits().length > 0) {
            // there is no point in adding empty search hits and merging them with the others. Also, empty search hits always come
            // without sort fields and collapse info, despite sort by field and/or field collapsing was requested, which causes
            // issues reconstructing the proper TopDocs instance and breaks mergeTopDocs which expects the same type for each result.
            topDocsList.add(topDocs);
        }
    }
    // after going through all the hits and collecting all their distinct shards, we assign shardIndex and set it to the ScoreDocs
    setTopDocsShardIndex(shards, topDocsList);
    TopDocs topDocs = SearchPhaseController.mergeTopDocs(topDocsList, size, from);
    SearchHits mergedSearchHits = topDocsToSearchHits(topDocs, topDocsStats);
    setSuggestShardIndex(shards, groupedSuggestions);
    Suggest suggest = groupedSuggestions.isEmpty() ? null : new Suggest(Suggest.reduce(groupedSuggestions));
    InternalAggregations reducedAggs = InternalAggregations.topLevelReduce(aggs, aggReduceContextBuilder.forFinalReduction());
    ShardSearchFailure[] shardFailures = failures.toArray(ShardSearchFailure.EMPTY_ARRAY);
    SearchProfileShardResults profileShardResults = profileResults.isEmpty() ? null : new SearchProfileShardResults(profileResults);
    // make failures ordering consistent between ordinary search and CCS by looking at the shard they come from
    Arrays.sort(shardFailures, FAILURES_COMPARATOR);
    InternalSearchResponse response = new InternalSearchResponse(mergedSearchHits, reducedAggs, suggest, profileShardResults, topDocsStats.timedOut, topDocsStats.terminatedEarly, numReducePhases);
    long tookInMillis = searchTimeProvider.buildTookInMillis();
    return new SearchResponse(response, null, totalShards, successfulShards, skippedShards, tookInMillis, shardFailures, clusters, null);
}
Also used : TotalHits(org.apache.lucene.search.TotalHits) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Suggest(org.opensearch.search.suggest.Suggest) TopDocsAndMaxScore(org.opensearch.common.lucene.search.TopDocsAndMaxScore) TopDocs(org.apache.lucene.search.TopDocs) CompletionSuggestion(org.opensearch.search.suggest.completion.CompletionSuggestion) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) SearchHits(org.opensearch.search.SearchHits) ProfileShardResult(org.opensearch.search.profile.ProfileShardResult) CompletionSuggestion(org.opensearch.search.suggest.completion.CompletionSuggestion) TreeMap(java.util.TreeMap) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) InternalAggregations(org.opensearch.search.aggregations.InternalAggregations) SearchProfileShardResults(org.opensearch.search.profile.SearchProfileShardResults) SearchShardTarget(org.opensearch.search.SearchShardTarget) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse)

Example 3 with InternalSearchResponse

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

the class SearchResponse method empty.

static SearchResponse empty(Supplier<Long> tookInMillisSupplier, Clusters clusters) {
    SearchHits searchHits = new SearchHits(new SearchHit[0], new TotalHits(0L, TotalHits.Relation.EQUAL_TO), Float.NaN);
    InternalSearchResponse internalSearchResponse = new InternalSearchResponse(searchHits, InternalAggregations.EMPTY, null, null, false, null, 0);
    return new SearchResponse(internalSearchResponse, null, 0, 0, 0, tookInMillisSupplier.get(), ShardSearchFailure.EMPTY_ARRAY, clusters, null);
}
Also used : TotalHits(org.apache.lucene.search.TotalHits) SearchHits(org.opensearch.search.SearchHits) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse)

Example 4 with InternalSearchResponse

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

the class CrossClusterSearchUnavailableClusterIT method startTransport.

private static MockTransportService startTransport(final String id, final List<DiscoveryNode> knownNodes, final Version version, final ThreadPool threadPool) {
    boolean success = false;
    final Settings s = Settings.builder().put("node.name", id).build();
    ClusterName clusterName = ClusterName.CLUSTER_NAME_SETTING.get(s);
    MockTransportService newService = MockTransportService.createNewService(s, version, threadPool, null);
    try {
        newService.registerRequestHandler(ClusterSearchShardsAction.NAME, ThreadPool.Names.SAME, ClusterSearchShardsRequest::new, (request, channel, task) -> {
            channel.sendResponse(new ClusterSearchShardsResponse(new ClusterSearchShardsGroup[0], knownNodes.toArray(new DiscoveryNode[0]), Collections.emptyMap()));
        });
        newService.registerRequestHandler(SearchAction.NAME, ThreadPool.Names.SAME, SearchRequest::new, (request, channel, task) -> {
            InternalSearchResponse response = new InternalSearchResponse(new SearchHits(new SearchHit[0], new TotalHits(0, TotalHits.Relation.EQUAL_TO), Float.NaN), InternalAggregations.EMPTY, null, null, false, null, 1);
            SearchResponse searchResponse = new SearchResponse(response, null, 1, 1, 0, 100, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY);
            channel.sendResponse(searchResponse);
        });
        newService.registerRequestHandler(ClusterStateAction.NAME, ThreadPool.Names.SAME, ClusterStateRequest::new, (request, channel, task) -> {
            DiscoveryNodes.Builder builder = DiscoveryNodes.builder();
            for (DiscoveryNode node : knownNodes) {
                builder.add(node);
            }
            ClusterState build = ClusterState.builder(clusterName).nodes(builder.build()).build();
            channel.sendResponse(new ClusterStateResponse(clusterName, build, false));
        });
        newService.start();
        newService.acceptIncomingRequests();
        success = true;
        return newService;
    } finally {
        if (success == false) {
            newService.close();
        }
    }
}
Also used : ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) TotalHits(org.apache.lucene.search.TotalHits) SearchRequest(org.opensearch.action.search.SearchRequest) ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MockTransportService(org.opensearch.test.transport.MockTransportService) ClusterStateResponse(org.opensearch.action.admin.cluster.state.ClusterStateResponse) ClusterStateRequest(org.opensearch.action.admin.cluster.state.ClusterStateRequest) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup) SearchResponse(org.opensearch.action.search.SearchResponse) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) ClusterSearchShardsRequest(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsRequest) ClusterName(org.opensearch.cluster.ClusterName) Settings(org.opensearch.common.settings.Settings) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse)

Example 5 with InternalSearchResponse

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

the class SearchResponseTests method createTestItem.

/**
 * if minimal is set, don't include search hits, aggregations, suggest etc... to make test simpler
 */
private SearchResponse createTestItem(boolean minimal, ShardSearchFailure... shardSearchFailures) {
    boolean timedOut = randomBoolean();
    Boolean terminatedEarly = randomBoolean() ? null : randomBoolean();
    int numReducePhases = randomIntBetween(1, 10);
    long tookInMillis = randomNonNegativeLong();
    int totalShards = randomIntBetween(1, Integer.MAX_VALUE);
    int successfulShards = randomIntBetween(0, totalShards);
    int skippedShards = randomIntBetween(0, totalShards);
    InternalSearchResponse internalSearchResponse;
    if (minimal == false) {
        SearchHits hits = SearchHitsTests.createTestItem(true, true);
        InternalAggregations aggregations = aggregationsTests.createTestInstance();
        Suggest suggest = SuggestTests.createTestItem();
        SearchProfileShardResults profileShardResults = SearchProfileShardResultsTests.createTestItem();
        internalSearchResponse = new InternalSearchResponse(hits, aggregations, suggest, profileShardResults, timedOut, terminatedEarly, numReducePhases);
    } else {
        internalSearchResponse = InternalSearchResponse.empty();
    }
    return new SearchResponse(internalSearchResponse, null, totalShards, successfulShards, skippedShards, tookInMillis, shardSearchFailures, randomBoolean() ? randomClusters() : SearchResponse.Clusters.EMPTY);
}
Also used : InternalAggregations(org.opensearch.search.aggregations.InternalAggregations) SearchProfileShardResults(org.opensearch.search.profile.SearchProfileShardResults) SearchHits(org.opensearch.search.SearchHits) Suggest(org.opensearch.search.suggest.Suggest) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse)

Aggregations

InternalSearchResponse (org.opensearch.search.internal.InternalSearchResponse)33 SearchHits (org.opensearch.search.SearchHits)20 TotalHits (org.apache.lucene.search.TotalHits)17 SearchHit (org.opensearch.search.SearchHit)13 SearchResponse (org.opensearch.action.search.SearchResponse)8 SearchTimeProvider (org.opensearch.action.search.TransportSearchAction.SearchTimeProvider)7 ArrayList (java.util.ArrayList)5 Suggest (org.opensearch.search.suggest.Suggest)5 HashMap (java.util.HashMap)4 InnerHitBuilder (org.opensearch.index.query.InnerHitBuilder)4 SearchShardTarget (org.opensearch.search.SearchShardTarget)4 InternalAggregations (org.opensearch.search.aggregations.InternalAggregations)4 SearchSourceBuilder (org.opensearch.search.builder.SearchSourceBuilder)4 CollapseBuilder (org.opensearch.search.collapse.CollapseBuilder)4 SearchProfileShardResults (org.opensearch.search.profile.SearchProfileShardResults)4 CompletionSuggestion (org.opensearch.search.suggest.completion.CompletionSuggestion)4 ShardId (org.opensearch.index.shard.ShardId)3 SearchPhaseResult (org.opensearch.search.SearchPhaseResult)3 List (java.util.List)2 Map (java.util.Map)2