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);
                }
            }
        }
Beispiel #2
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));
                }
            }
        }