示例#1
0
        public override void AddExplanation(ExplanationResult explanation)
        {
            if (Explanations == null)
            {
                Explanations = new Dictionary <string, string[]>();
            }

            if (Explanations.TryGetValue(explanation.Key, out var result) == false)
            {
                Explanations[explanation.Key] = new[] { CreateExplanation(explanation.Explanation) }
            }
            ;
            else
            {
                Array.Resize(ref result, result.Length + 1);
                result[result.Length - 1] = CreateExplanation(explanation.Explanation);
            }
        }
示例#2
0
 public override void AddExplanation(ExplanationResult explanationResult)
 {
     throw new NotSupportedException();
 }
 public abstract void AddExplanation(ExplanationResult explanationResult);
        public IEnumerable <(Document Result, Dictionary <string, Dictionary <string, string[]> > Highlightings, ExplanationResult Explanation)> Query(IndexQueryServerSide query, QueryTimingsScope queryTimings, FieldsToFetch fieldsToFetch, Reference <int> totalResults, Reference <int> skippedResults, IQueryResultRetriever retriever, DocumentsOperationContext documentsContext, Func <string, SpatialField> getSpatialField, CancellationToken token)
        {
            ExplanationOptions explanationOptions = null;

            var pageSize        = query.PageSize;
            var isDistinctCount = pageSize == 0 && query.Metadata.IsDistinct;

            if (isDistinctCount)
            {
                pageSize = int.MaxValue;
            }

            pageSize = GetPageSize(_searcher, pageSize);

            var docsToGet = pageSize;
            var position  = query.Start;

            if (query.Metadata.IsOptimizedSortOnly && _index.Definition.HasDynamicFields == false)
            {
                foreach (var result in QuerySortOnly(query, retriever, position, pageSize, totalResults, token))
                {
                    yield return(result);
                }

                yield break;
            }

            QueryTimingsScope luceneScope       = null;
            QueryTimingsScope highlightingScope = null;
            QueryTimingsScope explanationsScope = null;

            if (queryTimings != null)
            {
                luceneScope       = queryTimings.For(nameof(QueryTimingsScope.Names.Lucene), start: false);
                highlightingScope = query.Metadata.HasHighlightings
                    ? queryTimings.For(nameof(QueryTimingsScope.Names.Highlightings), start: false)
                    : null;
                explanationsScope = query.Metadata.HasExplanations
                    ? queryTimings.For(nameof(QueryTimingsScope.Names.Explanations), start: false)
                    : null;
            }

            var returnedResults = 0;

            var luceneQuery = GetLuceneQuery(documentsContext, query.Metadata, query.QueryParameters, _analyzer, _queryBuilderFactories);
            var sort        = GetSort(query, _index, getSpatialField, documentsContext);

            using (var scope = new IndexQueryingScope(_indexType, query, fieldsToFetch, _searcher, retriever, _state))
            {
                if (query.Metadata.HasHighlightings)
                {
                    using (highlightingScope?.For(nameof(QueryTimingsScope.Names.Setup)))
                        SetupHighlighter(query, luceneQuery, documentsContext);
                }

                while (true)
                {
                    token.ThrowIfCancellationRequested();

                    TopDocs search;
                    using (luceneScope?.Start())
                        search = ExecuteQuery(luceneQuery, query.Start, docsToGet, sort);

                    totalResults.Value = search.TotalHits;

                    scope.RecordAlreadyPagedItemsInPreviousPage(search);

                    for (; position < search.ScoreDocs.Length && pageSize > 0; position++)
                    {
                        token.ThrowIfCancellationRequested();

                        var scoreDoc = search.ScoreDocs[position];

                        global::Lucene.Net.Documents.Document document;
                        using (luceneScope?.Start())
                            document = _searcher.Doc(scoreDoc.Doc, _state);

                        if (retriever.TryGetKey(document, _state, out string key) && scope.WillProbablyIncludeInResults(key) == false)
                        {
                            skippedResults.Value++;
                            continue;
                        }

                        var result = retriever.Get(document, scoreDoc.Score, _state);
                        if (scope.TryIncludeInResults(result) == false)
                        {
                            skippedResults.Value++;
                            continue;
                        }

                        returnedResults++;

                        if (isDistinctCount == false)
                        {
                            Dictionary <string, Dictionary <string, string[]> > highlightings = null;
                            if (query.Metadata.HasHighlightings)
                            {
                                using (highlightingScope?.Start())
                                    highlightings = GetHighlighterResults(query, _searcher, scoreDoc, result, document, documentsContext);
                            }

                            ExplanationResult explanation = null;
                            if (query.Metadata.HasExplanations)
                            {
                                using (explanationsScope?.Start())
                                {
                                    if (explanationOptions == null)
                                    {
                                        explanationOptions = query.Metadata.Explanation.GetOptions(documentsContext, query.QueryParameters);
                                    }

                                    explanation = GetQueryExplanations(explanationOptions, luceneQuery, _searcher, scoreDoc, result, document);
                                }
                            }

                            yield return(result, highlightings, explanation);
                        }

                        if (returnedResults == pageSize)
                        {
                            yield break;
                        }
                    }

                    if (search.TotalHits == search.ScoreDocs.Length)
                    {
                        break;
                    }

                    if (returnedResults >= pageSize)
                    {
                        break;
                    }

                    Debug.Assert(_maxNumberOfOutputsPerDocument > 0);

                    docsToGet += GetPageSize(_searcher, (long)(pageSize - returnedResults) * _maxNumberOfOutputsPerDocument);
                }

                if (isDistinctCount)
                {
                    totalResults.Value = returnedResults;
                }
            }
        }