Search in sources :

Example 6 with QuerySearchResultProvider

use of org.elasticsearch.search.query.QuerySearchResultProvider in project elasticsearch by elastic.

the class SearchPhaseController method getHits.

private SearchHits getHits(ReducedQueryPhase reducedQueryPhase, boolean ignoreFrom, ScoreDoc[] sortedDocs, AtomicArray<? extends QuerySearchResultProvider> fetchResultsArr) {
    List<? extends AtomicArray.Entry<? extends QuerySearchResultProvider>> fetchResults = fetchResultsArr.asList();
    boolean sorted = false;
    int sortScoreIndex = -1;
    if (reducedQueryPhase.oneResult.topDocs() instanceof TopFieldDocs) {
        TopFieldDocs fieldDocs = (TopFieldDocs) reducedQueryPhase.oneResult.queryResult().topDocs();
        if (fieldDocs instanceof CollapseTopFieldDocs && fieldDocs.fields.length == 1 && fieldDocs.fields[0].getType() == SortField.Type.SCORE) {
            sorted = false;
        } else {
            sorted = true;
            for (int i = 0; i < fieldDocs.fields.length; i++) {
                if (fieldDocs.fields[i].getType() == SortField.Type.SCORE) {
                    sortScoreIndex = i;
                }
            }
        }
    }
    // clean the fetch counter
    for (AtomicArray.Entry<? extends QuerySearchResultProvider> entry : fetchResults) {
        entry.value.fetchResult().initCounter();
    }
    int from = ignoreFrom ? 0 : reducedQueryPhase.oneResult.queryResult().from();
    int numSearchHits = (int) Math.min(reducedQueryPhase.fetchHits - from, reducedQueryPhase.oneResult.size());
    // with collapsing we can have more fetch hits than sorted docs
    numSearchHits = Math.min(sortedDocs.length, numSearchHits);
    // merge hits
    List<SearchHit> hits = new ArrayList<>();
    if (!fetchResults.isEmpty()) {
        for (int i = 0; i < numSearchHits; i++) {
            ScoreDoc shardDoc = sortedDocs[i];
            QuerySearchResultProvider fetchResultProvider = fetchResultsArr.get(shardDoc.shardIndex);
            if (fetchResultProvider == null) {
                continue;
            }
            FetchSearchResult fetchResult = fetchResultProvider.fetchResult();
            int index = fetchResult.counterGetAndIncrement();
            if (index < fetchResult.hits().internalHits().length) {
                SearchHit searchHit = fetchResult.hits().internalHits()[index];
                searchHit.score(shardDoc.score);
                searchHit.shard(fetchResult.shardTarget());
                if (sorted) {
                    FieldDoc fieldDoc = (FieldDoc) shardDoc;
                    searchHit.sortValues(fieldDoc.fields, reducedQueryPhase.oneResult.sortValueFormats());
                    if (sortScoreIndex != -1) {
                        searchHit.score(((Number) fieldDoc.fields[sortScoreIndex]).floatValue());
                    }
                }
                hits.add(searchHit);
            }
        }
    }
    return new SearchHits(hits.toArray(new SearchHit[hits.size()]), reducedQueryPhase.totalHits, reducedQueryPhase.maxScore);
}
Also used : AtomicArray(org.elasticsearch.common.util.concurrent.AtomicArray) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) SearchHit(org.elasticsearch.search.SearchHit) FieldDoc(org.apache.lucene.search.FieldDoc) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) ArrayList(java.util.ArrayList) IntArrayList(com.carrotsearch.hppc.IntArrayList) CollapseTopFieldDocs(org.apache.lucene.search.grouping.CollapseTopFieldDocs) TopFieldDocs(org.apache.lucene.search.TopFieldDocs) ScoreDoc(org.apache.lucene.search.ScoreDoc) SearchHits(org.elasticsearch.search.SearchHits) CollapseTopFieldDocs(org.apache.lucene.search.grouping.CollapseTopFieldDocs)

Example 7 with QuerySearchResultProvider

use of org.elasticsearch.search.query.QuerySearchResultProvider in project elasticsearch by elastic.

the class SearchServiceTests method testSearchWhileIndexDeleted.

public void testSearchWhileIndexDeleted() throws IOException, InterruptedException {
    createIndex("index");
    client().prepareIndex("index", "type", "1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
    SearchService service = getInstanceFromNode(SearchService.class);
    IndicesService indicesService = getInstanceFromNode(IndicesService.class);
    IndexService indexService = indicesService.indexServiceSafe(resolveIndex("index"));
    IndexShard indexShard = indexService.getShard(0);
    AtomicBoolean running = new AtomicBoolean(true);
    CountDownLatch startGun = new CountDownLatch(1);
    Semaphore semaphore = new Semaphore(Integer.MAX_VALUE);
    final Thread thread = new Thread() {

        @Override
        public void run() {
            startGun.countDown();
            while (running.get()) {
                service.afterIndexRemoved(indexService.index(), indexService.getIndexSettings(), DELETED);
                if (randomBoolean()) {
                    // context in a non-sane way.
                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        throw new AssertionError(e);
                    }
                    client().prepareIndex("index", "type").setSource("field", "value").setRefreshPolicy(randomFrom(WriteRequest.RefreshPolicy.values())).execute(new ActionListener<IndexResponse>() {

                        @Override
                        public void onResponse(IndexResponse indexResponse) {
                            semaphore.release();
                        }

                        @Override
                        public void onFailure(Exception e) {
                            semaphore.release();
                        }
                    });
                }
            }
        }
    };
    thread.start();
    startGun.await();
    try {
        final int rounds = scaledRandomIntBetween(100, 10000);
        for (int i = 0; i < rounds; i++) {
            try {
                QuerySearchResultProvider querySearchResultProvider = service.executeQueryPhase(new ShardSearchLocalRequest(indexShard.shardId(), 1, SearchType.DEFAULT, new SearchSourceBuilder(), new String[0], false, new AliasFilter(null, Strings.EMPTY_ARRAY), 1.0f), new SearchTask(123L, "", "", "", null));
                IntArrayList intCursors = new IntArrayList(1);
                intCursors.add(0);
                ShardFetchRequest req = new ShardFetchRequest(querySearchResultProvider.id(), intCursors, null);
                service.executeFetchPhase(req, new SearchTask(123L, "", "", "", null));
            } catch (AlreadyClosedException ex) {
                throw ex;
            } catch (IllegalStateException ex) {
                assertEquals("search context is already closed can't increment refCount current count [0]", ex.getMessage());
            } catch (SearchContextMissingException ex) {
            // that's fine
            }
        }
    } finally {
        running.set(false);
        thread.join();
        semaphore.acquire(Integer.MAX_VALUE);
    }
}
Also used : AliasFilter(org.elasticsearch.search.internal.AliasFilter) ShardSearchLocalRequest(org.elasticsearch.search.internal.ShardSearchLocalRequest) IndexService(org.elasticsearch.index.IndexService) Semaphore(java.util.concurrent.Semaphore) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) SearchSourceBuilder(org.elasticsearch.search.builder.SearchSourceBuilder) SearchTask(org.elasticsearch.action.search.SearchTask) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) IndexShard(org.elasticsearch.index.shard.IndexShard) IndicesService(org.elasticsearch.indices.IndicesService) ShardFetchRequest(org.elasticsearch.search.fetch.ShardFetchRequest) CountDownLatch(java.util.concurrent.CountDownLatch) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) IOException(java.io.IOException) SearchPhaseExecutionException(org.elasticsearch.action.search.SearchPhaseExecutionException) ExecutionException(java.util.concurrent.ExecutionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) IndexResponse(org.elasticsearch.action.index.IndexResponse) IntArrayList(com.carrotsearch.hppc.IntArrayList)

Example 8 with QuerySearchResultProvider

use of org.elasticsearch.search.query.QuerySearchResultProvider in project elasticsearch by elastic.

the class SearchPhaseController method merge.

/**
     * Enriches search hits and completion suggestion hits from <code>sortedDocs</code> using <code>fetchResultsArr</code>,
     * merges suggestions, aggregations and profile results
     *
     * Expects sortedDocs to have top search docs across all shards, optionally followed by top suggest docs for each named
     * completion suggestion ordered by suggestion name
     */
public InternalSearchResponse merge(boolean ignoreFrom, ScoreDoc[] sortedDocs, ReducedQueryPhase reducedQueryPhase, AtomicArray<? extends QuerySearchResultProvider> fetchResultsArr) {
    if (reducedQueryPhase.isEmpty()) {
        return InternalSearchResponse.empty();
    }
    List<? extends AtomicArray.Entry<? extends QuerySearchResultProvider>> fetchResults = fetchResultsArr.asList();
    SearchHits hits = getHits(reducedQueryPhase, ignoreFrom, sortedDocs, fetchResultsArr);
    if (reducedQueryPhase.suggest != null) {
        if (!fetchResults.isEmpty()) {
            int currentOffset = hits.getHits().length;
            for (CompletionSuggestion suggestion : reducedQueryPhase.suggest.filter(CompletionSuggestion.class)) {
                final List<CompletionSuggestion.Entry.Option> suggestionOptions = suggestion.getOptions();
                for (int scoreDocIndex = currentOffset; scoreDocIndex < currentOffset + suggestionOptions.size(); scoreDocIndex++) {
                    ScoreDoc shardDoc = sortedDocs[scoreDocIndex];
                    QuerySearchResultProvider searchResultProvider = fetchResultsArr.get(shardDoc.shardIndex);
                    if (searchResultProvider == null) {
                        continue;
                    }
                    FetchSearchResult fetchResult = searchResultProvider.fetchResult();
                    int fetchResultIndex = fetchResult.counterGetAndIncrement();
                    if (fetchResultIndex < fetchResult.hits().internalHits().length) {
                        SearchHit hit = fetchResult.hits().internalHits()[fetchResultIndex];
                        CompletionSuggestion.Entry.Option suggestOption = suggestionOptions.get(scoreDocIndex - currentOffset);
                        hit.score(shardDoc.score);
                        hit.shard(fetchResult.shardTarget());
                        suggestOption.setHit(hit);
                    }
                }
                currentOffset += suggestionOptions.size();
            }
            assert currentOffset == sortedDocs.length : "expected no more score doc slices";
        }
    }
    return reducedQueryPhase.buildResponse(hits);
}
Also used : AtomicArray(org.elasticsearch.common.util.concurrent.AtomicArray) CompletionSuggestion(org.elasticsearch.search.suggest.completion.CompletionSuggestion) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) SearchHit(org.elasticsearch.search.SearchHit) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) ScoreDoc(org.apache.lucene.search.ScoreDoc) Entry(org.elasticsearch.search.suggest.Suggest.Suggestion.Entry) SearchHits(org.elasticsearch.search.SearchHits)

Example 9 with QuerySearchResultProvider

use of org.elasticsearch.search.query.QuerySearchResultProvider in project elasticsearch by elastic.

the class FetchSearchPhase method innerRun.

private void innerRun() throws IOException {
    final int numShards = context.getNumShards();
    final boolean isScrollSearch = context.getRequest().scroll() != null;
    ScoreDoc[] sortedShardDocs = searchPhaseController.sortDocs(isScrollSearch, queryResults);
    String scrollId = isScrollSearch ? TransportSearchHelper.buildScrollId(queryResults) : null;
    List<AtomicArray.Entry<QuerySearchResultProvider>> queryResultsAsList = queryResults.asList();
    final SearchPhaseController.ReducedQueryPhase reducedQueryPhase = resultConsumer.reduce();
    final boolean queryAndFetchOptimization = queryResults.length() == 1;
    final Runnable finishPhase = () -> moveToNextPhase(searchPhaseController, sortedShardDocs, scrollId, reducedQueryPhase, queryAndFetchOptimization ? queryResults : fetchResults);
    if (queryAndFetchOptimization) {
        assert queryResults.get(0) == null || queryResults.get(0).fetchResult() != null;
        // query AND fetch optimization
        finishPhase.run();
    } else {
        final IntArrayList[] docIdsToLoad = searchPhaseController.fillDocIdsToLoad(numShards, sortedShardDocs);
        if (sortedShardDocs.length == 0) {
            // no docs to fetch -- sidestep everything and return
            queryResultsAsList.stream().map(e -> e.value.queryResult()).forEach(// we have to release contexts here to free up resources
            this::releaseIrrelevantSearchContext);
            finishPhase.run();
        } else {
            final ScoreDoc[] lastEmittedDocPerShard = isScrollSearch ? searchPhaseController.getLastEmittedDocPerShard(reducedQueryPhase, sortedShardDocs, numShards) : null;
            final CountedCollector<FetchSearchResult> counter = new CountedCollector<>(fetchResults::set, // we count down every shard in the result no matter if we got any results or not
            docIdsToLoad.length, finishPhase, context);
            for (int i = 0; i < docIdsToLoad.length; i++) {
                IntArrayList entry = docIdsToLoad[i];
                QuerySearchResultProvider queryResult = queryResults.get(i);
                if (entry == null) {
                    // no results for this shard ID
                    if (queryResult != null) {
                        // if we got some hits from this shard we have to release the context there
                        // we do this as we go since it will free up resources and passing on the request on the
                        // transport layer is cheap.
                        releaseIrrelevantSearchContext(queryResult.queryResult());
                    }
                    // in any case we count down this result since we don't talk to this shard anymore
                    counter.countDown();
                } else {
                    Transport.Connection connection = context.getConnection(queryResult.shardTarget().getNodeId());
                    ShardFetchSearchRequest fetchSearchRequest = createFetchRequest(queryResult.queryResult().id(), i, entry, lastEmittedDocPerShard);
                    executeFetch(i, queryResult.shardTarget(), counter, fetchSearchRequest, queryResult.queryResult(), connection);
                }
            }
        }
    }
}
Also used : SearchShardTarget(org.elasticsearch.search.SearchShardTarget) InternalSearchResponse(org.elasticsearch.search.internal.InternalSearchResponse) Transport(org.elasticsearch.transport.Transport) ScoreDoc(org.apache.lucene.search.ScoreDoc) AtomicArray(org.elasticsearch.common.util.concurrent.AtomicArray) IOException(java.io.IOException) ShardFetchSearchRequest(org.elasticsearch.search.fetch.ShardFetchSearchRequest) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) Function(java.util.function.Function) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) List(java.util.List) Logger(org.apache.logging.log4j.Logger) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) QuerySearchResult(org.elasticsearch.search.query.QuerySearchResult) Supplier(org.apache.logging.log4j.util.Supplier) IntArrayList(com.carrotsearch.hppc.IntArrayList) ActionRunnable(org.elasticsearch.action.ActionRunnable) ActionListener(org.elasticsearch.action.ActionListener) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) ScoreDoc(org.apache.lucene.search.ScoreDoc) ShardFetchSearchRequest(org.elasticsearch.search.fetch.ShardFetchSearchRequest) ActionRunnable(org.elasticsearch.action.ActionRunnable) IntArrayList(com.carrotsearch.hppc.IntArrayList) Transport(org.elasticsearch.transport.Transport)

Example 10 with QuerySearchResultProvider

use of org.elasticsearch.search.query.QuerySearchResultProvider in project elasticsearch by elastic.

the class FetchSearchPhaseTests method testFetchTwoDocument.

public void testFetchTwoDocument() throws IOException {
    MockSearchPhaseContext mockSearchPhaseContext = new MockSearchPhaseContext(2);
    SearchPhaseController controller = new SearchPhaseController(Settings.EMPTY, BigArrays.NON_RECYCLING_INSTANCE, null);
    InitialSearchPhase.SearchPhaseResults<QuerySearchResultProvider> results = controller.newSearchPhaseResults(mockSearchPhaseContext.getRequest(), 2);
    AtomicReference<SearchResponse> responseRef = new AtomicReference<>();
    int resultSetSize = randomIntBetween(2, 10);
    QuerySearchResult queryResult = new QuerySearchResult(123, new SearchShardTarget("node1", new Index("test", "na"), 0));
    queryResult.topDocs(new TopDocs(1, new ScoreDoc[] { new ScoreDoc(42, 1.0F) }, 2.0F), new DocValueFormat[0]);
    // the size of the result set
    queryResult.size(resultSetSize);
    results.consumeResult(0, queryResult);
    queryResult = new QuerySearchResult(321, new SearchShardTarget("node2", new Index("test", "na"), 1));
    queryResult.topDocs(new TopDocs(1, new ScoreDoc[] { new ScoreDoc(84, 2.0F) }, 2.0F), new DocValueFormat[0]);
    queryResult.size(resultSetSize);
    results.consumeResult(1, queryResult);
    SearchTransportService searchTransportService = new SearchTransportService(Settings.builder().put("search.remote.connect", false).build(), null, null) {

        @Override
        public void sendExecuteFetch(Transport.Connection connection, ShardFetchSearchRequest request, SearchTask task, ActionListener<FetchSearchResult> listener) {
            FetchSearchResult fetchResult = new FetchSearchResult();
            if (request.id() == 321) {
                fetchResult.hits(new SearchHits(new SearchHit[] { new SearchHit(84) }, 1, 2.0F));
            } else {
                assertEquals(123, request.id());
                fetchResult.hits(new SearchHits(new SearchHit[] { new SearchHit(42) }, 1, 1.0F));
            }
            listener.onResponse(fetchResult);
        }
    };
    mockSearchPhaseContext.searchTransport = searchTransportService;
    FetchSearchPhase phase = new FetchSearchPhase(results, controller, mockSearchPhaseContext, (searchResponse) -> new SearchPhase("test") {

        @Override
        public void run() throws IOException {
            responseRef.set(searchResponse);
        }
    });
    assertEquals("fetch", phase.getName());
    phase.run();
    mockSearchPhaseContext.assertNoFailure();
    assertNotNull(responseRef.get());
    assertEquals(2, responseRef.get().getHits().totalHits);
    assertEquals(84, responseRef.get().getHits().getAt(0).docId());
    assertEquals(42, responseRef.get().getHits().getAt(1).docId());
    assertEquals(0, responseRef.get().getFailedShards());
    assertEquals(2, responseRef.get().getSuccessfulShards());
    assertTrue(mockSearchPhaseContext.releasedSearchContexts.isEmpty());
}
Also used : SearchHit(org.elasticsearch.search.SearchHit) QueryFetchSearchResult(org.elasticsearch.search.fetch.QueryFetchSearchResult) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) Index(org.elasticsearch.index.Index) ScoreDoc(org.apache.lucene.search.ScoreDoc) TopDocs(org.apache.lucene.search.TopDocs) ShardFetchSearchRequest(org.elasticsearch.search.fetch.ShardFetchSearchRequest) SearchHits(org.elasticsearch.search.SearchHits) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) ActionListener(org.elasticsearch.action.ActionListener) QuerySearchResult(org.elasticsearch.search.query.QuerySearchResult) SearchShardTarget(org.elasticsearch.search.SearchShardTarget)

Aggregations

QuerySearchResultProvider (org.elasticsearch.search.query.QuerySearchResultProvider)17 ScoreDoc (org.apache.lucene.search.ScoreDoc)15 SearchShardTarget (org.elasticsearch.search.SearchShardTarget)11 FetchSearchResult (org.elasticsearch.search.fetch.FetchSearchResult)10 IOException (java.io.IOException)9 TopDocs (org.apache.lucene.search.TopDocs)9 Index (org.elasticsearch.index.Index)9 SearchHit (org.elasticsearch.search.SearchHit)9 SearchHits (org.elasticsearch.search.SearchHits)9 QuerySearchResult (org.elasticsearch.search.query.QuerySearchResult)9 ActionListener (org.elasticsearch.action.ActionListener)7 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 AtomicArray (org.elasticsearch.common.util.concurrent.AtomicArray)6 QueryFetchSearchResult (org.elasticsearch.search.fetch.QueryFetchSearchResult)6 ShardFetchSearchRequest (org.elasticsearch.search.fetch.ShardFetchSearchRequest)6 ArrayList (java.util.ArrayList)5 CompletionSuggestion (org.elasticsearch.search.suggest.completion.CompletionSuggestion)5 Suggest (org.elasticsearch.search.suggest.Suggest)4 IntArrayList (com.carrotsearch.hppc.IntArrayList)3 CountDownLatch (java.util.concurrent.CountDownLatch)3