All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensearch.search.internal.SearchContext Maven / Gradle / Ivy

There is a newer version: 2.18.0
Show newest version
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * The OpenSearch Contributors require contributions made to
 * this file be licensed under the Apache-2.0 license or a
 * compatible open source license.
 */

/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

package org.opensearch.search.internal;

import org.apache.lucene.search.Collector;
import org.apache.lucene.search.CollectorManager;
import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.Query;
import org.opensearch.action.search.SearchShardTask;
import org.opensearch.action.search.SearchType;
import org.opensearch.common.Nullable;
import org.opensearch.common.annotation.PublicApi;
import org.opensearch.common.lease.Releasable;
import org.opensearch.common.lease.Releasables;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.common.util.BigArrays;
import org.opensearch.index.cache.bitset.BitsetFilterCache;
import org.opensearch.index.mapper.MappedFieldType;
import org.opensearch.index.mapper.MapperService;
import org.opensearch.index.mapper.ObjectMapper;
import org.opensearch.index.query.ParsedQuery;
import org.opensearch.index.query.QueryShardContext;
import org.opensearch.index.shard.IndexShard;
import org.opensearch.index.similarity.SimilarityService;
import org.opensearch.search.RescoreDocIds;
import org.opensearch.search.SearchExtBuilder;
import org.opensearch.search.SearchShardTarget;
import org.opensearch.search.aggregations.Aggregator;
import org.opensearch.search.aggregations.BucketCollectorProcessor;
import org.opensearch.search.aggregations.InternalAggregation;
import org.opensearch.search.aggregations.SearchContextAggregations;
import org.opensearch.search.aggregations.bucket.LocalBucketCountThresholds;
import org.opensearch.search.aggregations.bucket.terms.TermsAggregator;
import org.opensearch.search.collapse.CollapseContext;
import org.opensearch.search.dfs.DfsSearchResult;
import org.opensearch.search.fetch.FetchPhase;
import org.opensearch.search.fetch.FetchSearchResult;
import org.opensearch.search.fetch.StoredFieldsContext;
import org.opensearch.search.fetch.subphase.FetchDocValuesContext;
import org.opensearch.search.fetch.subphase.FetchFieldsContext;
import org.opensearch.search.fetch.subphase.FetchSourceContext;
import org.opensearch.search.fetch.subphase.InnerHitsContext;
import org.opensearch.search.fetch.subphase.ScriptFieldsContext;
import org.opensearch.search.fetch.subphase.highlight.SearchHighlightContext;
import org.opensearch.search.profile.Profilers;
import org.opensearch.search.query.QuerySearchResult;
import org.opensearch.search.query.ReduceableSearchResult;
import org.opensearch.search.rescore.RescoreContext;
import org.opensearch.search.sort.SortAndFormats;
import org.opensearch.search.suggest.SuggestionSearchContext;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * This class encapsulates the state needed to execute a search. It holds a reference to the
 * shards point in time snapshot (IndexReader / ContextIndexSearcher) and allows passing on
 * state from one query / fetch phase to another.
 *
 * @opensearch.api
 */
@PublicApi(since = "1.0.0")
public abstract class SearchContext implements Releasable {

    public static final int DEFAULT_TERMINATE_AFTER = 0;
    public static final int TRACK_TOTAL_HITS_ACCURATE = Integer.MAX_VALUE;
    public static final int TRACK_TOTAL_HITS_DISABLED = -1;
    public static final int DEFAULT_TRACK_TOTAL_HITS_UP_TO = 10000;

    // no-op bucket collector processor
    public static final BucketCollectorProcessor NO_OP_BUCKET_COLLECTOR_PROCESSOR = new BucketCollectorProcessor() {
        @Override
        public void processPostCollection(Collector collectorTree) {
            // do nothing as there is no aggregation collector
        }

        @Override
        public List toAggregators(Collection collectors) {
            // should not be called when there is no aggregation collector
            throw new IllegalStateException("Unexpected toAggregators call on NO_OP_BUCKET_COLLECTOR_PROCESSOR");
        }
    };

    private final List releasables = new CopyOnWriteArrayList<>();
    private final AtomicBoolean closed = new AtomicBoolean(false);
    private InnerHitsContext innerHitsContext;

    private volatile boolean searchTimedOut;

    protected SearchContext() {}

    public abstract void setTask(SearchShardTask task);

    public abstract SearchShardTask getTask();

    public abstract boolean isCancelled();

    public boolean isSearchTimedOut() {
        return this.searchTimedOut;
    }

    public void setSearchTimedOut(boolean searchTimedOut) {
        this.searchTimedOut = searchTimedOut;
    }

    @Override
    public final void close() {
        if (closed.compareAndSet(false, true)) {
            try {
                Releasables.close(releasables);
            } finally {
                doClose();
            }
        }
    }

    protected abstract void doClose();

    /**
     * Should be called before executing the main query and after all other parameters have been set.
     * @param rewrite if the set query should be rewritten against the searcher returned from {@link #searcher()}
     */
    public abstract void preProcess(boolean rewrite);

    /** Automatically apply all required filters to the given query such as
     *  alias filters, types filters, etc. */
    public abstract Query buildFilteredQuery(Query query);

    public abstract ShardSearchContextId id();

    public abstract String source();

    public abstract ShardSearchRequest request();

    public abstract SearchType searchType();

    public abstract SearchShardTarget shardTarget();

    public abstract int numberOfShards();

    public abstract float queryBoost();

    public abstract ScrollContext scrollContext();

    public abstract SearchContextAggregations aggregations();

    public abstract SearchContext aggregations(SearchContextAggregations aggregations);

    public abstract void addSearchExt(SearchExtBuilder searchExtBuilder);

    public abstract SearchExtBuilder getSearchExt(String name);

    public abstract SearchHighlightContext highlight();

    public abstract void highlight(SearchHighlightContext highlight);

    public InnerHitsContext innerHits() {
        if (innerHitsContext == null) {
            innerHitsContext = new InnerHitsContext();
        }
        return innerHitsContext;
    }

    public abstract SuggestionSearchContext suggest();

    public abstract void suggest(SuggestionSearchContext suggest);

    /**
     * @return list of all rescore contexts.  empty if there aren't any.
     */
    public abstract List rescore();

    public abstract void addRescore(RescoreContext rescore);

    public final RescoreDocIds rescoreDocIds() {
        final List rescore = rescore();
        if (rescore == null) {
            return RescoreDocIds.EMPTY;
        }
        Map> rescoreDocIds = null;
        for (int i = 0; i < rescore.size(); i++) {
            final Set docIds = rescore.get(i).getRescoredDocs();
            if (docIds != null && docIds.isEmpty() == false) {
                if (rescoreDocIds == null) {
                    rescoreDocIds = new HashMap<>();
                }
                rescoreDocIds.put(i, docIds);
            }
        }
        return rescoreDocIds == null ? RescoreDocIds.EMPTY : new RescoreDocIds(rescoreDocIds);
    }

    public final void assignRescoreDocIds(RescoreDocIds rescoreDocIds) {
        final List rescore = rescore();
        if (rescore != null) {
            for (int i = 0; i < rescore.size(); i++) {
                final Set docIds = rescoreDocIds.getId(i);
                if (docIds != null) {
                    rescore.get(i).setRescoredDocs(docIds);
                }
            }
        }
    }

    public abstract boolean hasScriptFields();

    public abstract ScriptFieldsContext scriptFields();

    /**
     * A shortcut function to see whether there is a fetchSourceContext and it says the source is requested.
     */
    public abstract boolean sourceRequested();

    public abstract boolean hasFetchSourceContext();

    public abstract FetchSourceContext fetchSourceContext();

    public abstract SearchContext fetchSourceContext(FetchSourceContext fetchSourceContext);

    public abstract FetchDocValuesContext docValuesContext();

    public abstract SearchContext docValuesContext(FetchDocValuesContext docValuesContext);

    /**
     * The context related to retrieving fields.
     */
    public abstract FetchFieldsContext fetchFieldsContext();

    /**
     * Sets the context related to retrieving fields.
     */
    public abstract SearchContext fetchFieldsContext(FetchFieldsContext fetchFieldsContext);

    public abstract ContextIndexSearcher searcher();

    public abstract IndexShard indexShard();

    public abstract MapperService mapperService();

    public abstract SimilarityService similarityService();

    public abstract BigArrays bigArrays();

    public abstract BitsetFilterCache bitsetFilterCache();

    public abstract TimeValue timeout();

    public abstract void timeout(TimeValue timeout);

    public abstract int terminateAfter();

    public abstract void terminateAfter(int terminateAfter);

    /**
     * Indicates if the current index should perform frequent low level search cancellation check.
     * 

* Enabling low-level checks will make long running searches to react to the cancellation request faster. However, * since it will produce more cancellation checks it might slow the search performance down. */ public abstract boolean lowLevelCancellation(); public abstract SearchContext minimumScore(float minimumScore); public abstract Float minimumScore(); public abstract SearchContext sort(SortAndFormats sort); public abstract SortAndFormats sort(); public abstract SearchContext trackScores(boolean trackScores); public abstract boolean trackScores(); public abstract SearchContext trackTotalHitsUpTo(int trackTotalHits); /** * Indicates the total number of hits to count accurately. * Defaults to {@link #DEFAULT_TRACK_TOTAL_HITS_UP_TO}. */ public abstract int trackTotalHitsUpTo(); public abstract SearchContext searchAfter(FieldDoc searchAfter); public abstract FieldDoc searchAfter(); public abstract SearchContext collapse(CollapseContext collapse); public abstract CollapseContext collapse(); public abstract SearchContext parsedPostFilter(ParsedQuery postFilter); public abstract ParsedQuery parsedPostFilter(); public abstract Query aliasFilter(); public abstract SearchContext parsedQuery(ParsedQuery query); public abstract ParsedQuery parsedQuery(); /** * The query to execute, might be rewritten. */ public abstract Query query(); public abstract int from(); public abstract SearchContext from(int from); public abstract int size(); public abstract SearchContext size(int size); public abstract boolean hasStoredFields(); public abstract boolean hasStoredFieldsContext(); /** * A shortcut function to see whether there is a storedFieldsContext and it says the fields are requested. */ public abstract boolean storedFieldsRequested(); public abstract StoredFieldsContext storedFieldsContext(); public abstract SearchContext storedFieldsContext(StoredFieldsContext storedFieldsContext); public abstract boolean explain(); public abstract void explain(boolean explain); @Nullable public abstract List groupStats(); public abstract void groupStats(List groupStats); public abstract boolean version(); public abstract void version(boolean version); /** indicates whether the sequence number and primary term of the last modification to each hit should be returned */ public abstract boolean seqNoAndPrimaryTerm(); /** controls whether the sequence number and primary term of the last modification to each hit should be returned */ public abstract void seqNoAndPrimaryTerm(boolean seqNoAndPrimaryTerm); public abstract int[] docIdsToLoad(); public abstract int docIdsToLoadFrom(); public abstract int docIdsToLoadSize(); public abstract SearchContext docIdsToLoad(int[] docIdsToLoad, int docsIdsToLoadFrom, int docsIdsToLoadSize); public abstract DfsSearchResult dfsResult(); public abstract QuerySearchResult queryResult(); public abstract FetchPhase fetchPhase(); public abstract FetchSearchResult fetchResult(); /** * Return a handle over the profilers for the current search request, or {@code null} if profiling is not enabled. */ public abstract Profilers getProfilers(); /** * Returns concurrent segment search status for the search context */ public boolean shouldUseConcurrentSearch() { return false; } /** * Returns local bucket count thresholds based on concurrent segment search status */ public LocalBucketCountThresholds asLocalBucketCountThresholds(TermsAggregator.BucketCountThresholds bucketCountThresholds) { return new LocalBucketCountThresholds( shouldUseConcurrentSearch() ? 0 : bucketCountThresholds.getShardMinDocCount(), bucketCountThresholds.getShardSize() ); } /** * Adds a releasable that will be freed when this context is closed. */ public void addReleasable(Releasable releasable) { releasables.add(releasable); } /** * @return true if the request contains only suggest */ public final boolean hasOnlySuggest() { return request().source() != null && request().source().isSuggestOnly(); } /** * Given the full name of a field, returns its {@link MappedFieldType}. */ public abstract MappedFieldType fieldType(String name); public abstract ObjectMapper getObjectMapper(String name); /** * Returns time in milliseconds that can be used for relative time calculations. * WARN: This is not the epoch time and can be a cached time. */ public abstract long getRelativeTimeInMillis(); /** * Returns time in milliseconds that can be used for relative time calculations. this method will fall back to * {@link SearchContext#getRelativeTimeInMillis()} (which might be a cached time) if useCache was set to true else it will be just be a * wrapper of {@link System#nanoTime()} converted to milliseconds. * @param useCache to allow using cached time if true or forcing calling {@link System#nanoTime()} if false * @return Returns time in milliseconds that can be used for relative time calculations. */ public long getRelativeTimeInMillis(boolean useCache) { if (useCache) { return getRelativeTimeInMillis(); } return TimeValue.nsecToMSec(System.nanoTime()); } /** Return a view of the additional query collector managers that should be run for this context. */ public abstract Map, CollectorManager> queryCollectorManagers(); public abstract QueryShardContext getQueryShardContext(); @Override public String toString() { StringBuilder result = new StringBuilder().append(shardTarget()); if (searchType() != SearchType.DEFAULT) { result.append("searchType=[").append(searchType()).append("]"); } if (scrollContext() != null) { if (scrollContext().scroll != null) { result.append("scroll=[").append(scrollContext().scroll.keepAlive()).append("]"); } else { result.append("scroll=[null]"); } } result.append(" query=[").append(query()).append("]"); return result.toString(); } public abstract ReaderContext readerContext(); public abstract InternalAggregation.ReduceContext partialOnShard(); // processor used for bucket collectors public abstract void setBucketCollectorProcessor(BucketCollectorProcessor bucketCollectorProcessor); public abstract BucketCollectorProcessor bucketCollectorProcessor(); public abstract boolean shouldUseTimeSeriesDescSortOptimization(); public abstract int getTargetMaxSliceCount(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy