public T ExecuteScalar <T>(QueryModel queryModel)
        {
            var luceneQueryModel = PrepareQuery(queryModel);

            var searcherHandle = CheckoutSearcher();

            using (searcherHandle)
            {
                var searcher    = searcherHandle.Searcher;
                var skipResults = luceneQueryModel.SkipResults;
                var maxResults  = Math.Min(luceneQueryModel.MaxResults, searcher.MaxDoc - skipResults);

                TopFieldDocs hits;

                if (maxResults > 0)
                {
                    var executionContext = new QueryExecutionContext(searcher, luceneQueryModel.Query, luceneQueryModel.Filter);
                    PrepareSearchSettings(executionContext);

                    hits = searcher.Search(executionContext.Query, executionContext.Filter, maxResults, luceneQueryModel.Sort);
                }
                else
                {
                    hits = new TopFieldDocs(0, new ScoreDoc[0], new SortField[0], 0);
                }

                var handler = ScalarResultHandlerRegistry.Instance.GetItem(luceneQueryModel.ResultSetOperator.GetType());

                return(handler.Execute <T>(luceneQueryModel, hits));
            }
        }
        public IEnumerable <T> ExecuteCollection <T>(QueryModel queryModel)
        {
            var itemHolder = new ItemHolder();

            var currentItemExpression = Expression.Property(Expression.Constant(itemHolder), "Current");

            var luceneQueryModel = PrepareQuery(queryModel);

            var mapping = new QuerySourceMapping();

            mapping.AddMapping(queryModel.MainFromClause, currentItemExpression);
            queryModel.TransformExpressions(e => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(e, mapping, throwOnUnmappedReferences: false));

            var projection = GetProjector <T>(queryModel);
            var projector  = projection.Compile();

            var searcherHandle = CheckoutSearcher();

            using (searcherHandle)
            {
                var searcher    = searcherHandle.Searcher;
                var skipResults = luceneQueryModel.SkipResults;
                var maxResults  = Math.Min(luceneQueryModel.MaxResults, searcher.MaxDoc - skipResults);
                var query       = luceneQueryModel.Query;

                var scoreFunction = luceneQueryModel.GetCustomScoreFunction <TDocument>();
                if (scoreFunction != null)
                {
                    query = new DelegatingCustomScoreQuery <TDocument>(query, ConvertDocumentForCustomBoost, scoreFunction);
                }

                var executionContext = new QueryExecutionContext(searcher, query, luceneQueryModel.Filter);

                PrepareSearchSettings(executionContext);

                var hits = searcher.Search(executionContext.Query, executionContext.Filter, maxResults + skipResults, luceneQueryModel.Sort);

                if (luceneQueryModel.Last)
                {
                    skipResults = hits.ScoreDocs.Length - 1;
                    if (skipResults < 0)
                    {
                        yield break;
                    }
                }

                var tracker = luceneQueryModel.DocumentTracker as IRetrievedDocumentTracker <TDocument>;

                executionContext.Phase = QueryExecutionPhase.ConvertResults;
                executionContext.Hits  = hits;

                foreach (var p in EnumerateHits(hits, executionContext, searcher, tracker, itemHolder, skipResults, projector))
                {
                    yield return(p);
                }
            }
        }
        public T ExecuteScalar <T>(QueryModel queryModel)
        {
            var watch = new Stopwatch();

            watch.Start();

            var luceneQueryModel = PrepareQuery(queryModel);

            var searcherHandle = CheckoutSearcher();

            using (searcherHandle)
            {
                var searcher    = searcherHandle.Searcher;
                var skipResults = luceneQueryModel.SkipResults;
                var maxResults  = Math.Min(luceneQueryModel.MaxResults, searcher.MaxDoc - skipResults);

                var          executionContext = new QueryExecutionContext(searcher, luceneQueryModel.Query, luceneQueryModel.Filter);
                TopFieldDocs hits;

                TimeSpan elapsedPreparationTime;
                TimeSpan elapsedSearchTime;

                if (maxResults > 0)
                {
                    PrepareSearchSettings(executionContext);

                    elapsedPreparationTime = watch.Elapsed;

                    hits = searcher.Search(executionContext.Query, executionContext.Filter, maxResults, luceneQueryModel.Sort);

                    elapsedSearchTime = watch.Elapsed - elapsedPreparationTime;
                }
                else
                {
                    hits = new TopFieldDocs(0, new ScoreDoc[0], new SortField[0], 0);
                    elapsedPreparationTime = watch.Elapsed;
                    elapsedSearchTime      = TimeSpan.Zero;
                }

                executionContext.Phase = QueryExecutionPhase.ConvertResults;
                executionContext.Hits  = hits;

                var handler = ScalarResultHandlerRegistry.Instance.GetItem(luceneQueryModel.ResultSetOperator.GetType());

                var result = handler.Execute <T>(luceneQueryModel, hits);

                var elapsedRetrievalTime = watch.Elapsed - elapsedPreparationTime - elapsedSearchTime;
                RaiseStatisticsCallback(luceneQueryModel, executionContext, elapsedPreparationTime, elapsedSearchTime, elapsedRetrievalTime, 0, 0);

                return(result);
            }
        }
        private void RaiseStatisticsCallback(LuceneQueryModel luceneQueryModel, QueryExecutionContext executionContext, TimeSpan elapsedPreparationTime, TimeSpan elapsedSearchTime, TimeSpan elapsedRetrievalTime, int skipResults, int retrievedDocuments)
        {
            var statistics = new LuceneQueryStatistics(executionContext.Query,
                                                       executionContext.Filter,
                                                       luceneQueryModel.Sort,
                                                       elapsedPreparationTime,
                                                       elapsedSearchTime,
                                                       elapsedRetrievalTime,
                                                       executionContext.Hits.TotalHits,
                                                       skipResults, retrievedDocuments);

            luceneQueryModel.RaiseCaptureQueryStatistics(statistics);
        }
        private IEnumerable <T> EnumerateHits <T>(TopDocs hits, QueryExecutionContext executionContext, Searchable searcher, IRetrievedDocumentTracker <TDocument> tracker, ItemHolder itemHolder, int skipResults, Func <TDocument, T> projector)
        {
            for (var i = skipResults; i < hits.ScoreDocs.Length; i++)
            {
                executionContext.CurrentHit      = i;
                executionContext.CurrentScoreDoc = hits.ScoreDocs[i];

                var docNum   = hits.ScoreDocs[i].Doc;
                var document = searcher.Doc(docNum);

                if (tracker == null)
                {
                    itemHolder.Current = ConvertDocument(document, executionContext);
                    yield return(projector(itemHolder.Current));

                    continue;
                }

                var key = GetDocumentKey(document, executionContext);

                if (tracker.IsMarkedForDeletion(key))
                {
                    continue;
                }

                TDocument item;
                if (!tracker.TryGetTrackedDocument(key, out item))
                {
                    item = ConvertDocument(document, executionContext);
                    tracker.TrackDocument(key, item, document);
                }

                itemHolder.Current = item;
                yield return(projector(itemHolder.Current));
            }
        }
예제 #6
0
        public IEnumerable <T> ExecuteCollection <T>(QueryModel queryModel)
        {
            var itemHolder = new ItemHolder();

            var currentItemExpression = Expression.Property(Expression.Constant(itemHolder), "Current");

            var luceneQueryModel = PrepareQuery(queryModel);

            var mapping = new QuerySourceMapping();

            mapping.AddMapping(queryModel.MainFromClause, currentItemExpression);
            queryModel.TransformExpressions(e => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(e, mapping, throwOnUnmappedReferences: true));

            var projection = GetProjector <T>(queryModel);
            var projector  = projection.Compile();

            var searcherHandle = CheckoutSearcher();

            using (searcherHandle)
            {
                var searcher    = searcherHandle.Searcher;
                var skipResults = luceneQueryModel.SkipResults;
                var maxResults  = Math.Min(luceneQueryModel.MaxResults, searcher.MaxDoc - skipResults);
                var query       = luceneQueryModel.Query;

                var scoreFunction = luceneQueryModel.GetCustomScoreFunction <TDocument>();
                if (scoreFunction != null)
                {
                    query = new DelegatingCustomScoreQuery <TDocument>(query, ConvertDocumentForCustomBoost, scoreFunction);
                }

                var executionContext = new QueryExecutionContext(searcher, query, luceneQueryModel.Filter);

                PrepareSearchSettings(executionContext);

                var hits = searcher.Search(executionContext.Query, executionContext.Filter, maxResults + skipResults, luceneQueryModel.Sort);

                if (luceneQueryModel.Last)
                {
                    skipResults = hits.ScoreDocs.Length - 1;
                    if (skipResults < 0)
                    {
                        yield break;
                    }
                }

                var tracker = luceneQueryModel.DocumentTracker as IRetrievedDocumentTracker <TDocument>;

                executionContext.Phase = QueryExecutionPhase.ConvertResults;
                executionContext.Hits  = hits;

                for (var i = skipResults; i < hits.ScoreDocs.Length; i++)
                {
                    executionContext.CurrentHit      = i;
                    executionContext.CurrentScoreDoc = hits.ScoreDocs[i];

                    var doc = hits.ScoreDocs[i].Doc;

                    var item = ConvertDocument(searcher.Doc(doc), executionContext);

                    if (tracker != null)
                    {
                        if (tracker.IsMarkedForDeletion(item))
                        {
                            continue;
                        }

                        TDocument tracked;

                        if (tracker.TryGetTrackedDocument(item, out tracked))
                        {
                            item = tracked;
                        }
                        else
                        {
                            var copy = ConvertDocument(searcher.Doc(doc), executionContext);
                            tracker.TrackDocument(item, copy);
                        }
                    }

                    itemHolder.Current = item;
                    yield return(projector(itemHolder.Current));
                }
            }
        }