Example #1
0
        //LUCENENET Specific. One of two methods that replace GroupByFieldOrFunction. Used support
        //          SearchByFunction in a way that eliminates casting for the caller.
        //          This method is essentually a Function specific version of the GroupByFieldOrFunction.
        protected virtual ITopGroups <TMutableValue> GroupByFunction <TMutableValue>(IndexSearcher searcher, Filter filter, Query query, int groupOffset, int groupLimit)
            where TMutableValue : MutableValue
        {
            int topN = groupOffset + groupLimit;
            FunctionFirstPassGroupingCollector <TMutableValue> firstPassCollector;
            FunctionAllGroupsCollector <TMutableValue>         allGroupsCollector;
            AbstractAllGroupHeadsCollector allGroupHeadsCollector;

            if (groupFunction == null)
            {
                throw IllegalStateException.Create("groupFunction must be set via the constructor by specifying a ValueSource.");
            }

            firstPassCollector = new FunctionFirstPassGroupingCollector <TMutableValue>(groupFunction, valueSourceContext, groupSort, topN);
            if (allGroups)
            {
                allGroupsCollector = new FunctionAllGroupsCollector <TMutableValue>(groupFunction, valueSourceContext);
            }
            else
            {
                allGroupsCollector = null;
            }
            if (allGroupHeads)
            {
                allGroupHeadsCollector = new FunctionAllGroupHeadsCollector(groupFunction, valueSourceContext, sortWithinGroup);
            }
            else
            {
                allGroupHeadsCollector = null;
            }


            ICollector firstRound;

            if (allGroupHeads || allGroups)
            {
                List <ICollector> collectors = new List <ICollector>();
                collectors.Add(firstPassCollector);

                if (allGroups)
                {
                    collectors.Add(allGroupsCollector);
                }
                if (allGroupHeads)
                {
                    collectors.Add(allGroupHeadsCollector);
                }
                firstRound = MultiCollector.Wrap(collectors.ToArray(/* new Collector[collectors.size()] */));
            }
            else
            {
                firstRound = firstPassCollector;
            }

            CachingCollector cachedCollector = null;

            if (maxCacheRAMMB != null || maxDocsToCache != null)
            {
                if (maxCacheRAMMB != null)
                {
                    cachedCollector = CachingCollector.Create(firstRound, cacheScores, maxCacheRAMMB.Value);
                }
                else
                {
                    cachedCollector = CachingCollector.Create(firstRound, cacheScores, maxDocsToCache.Value);
                }
                searcher.Search(query, filter, cachedCollector);
            }
            else
            {
                searcher.Search(query, filter, firstRound);
            }

            if (allGroups)
            {
                matchingGroups = (ICollection)allGroupsCollector.Groups;
            }
            else
            {
                matchingGroups = (ICollection)Collections.EmptyList <TMutableValue>();
            }
            if (allGroupHeads)
            {
                matchingGroupHeads = allGroupHeadsCollector.RetrieveGroupHeads(searcher.IndexReader.MaxDoc);
            }
            else
            {
                matchingGroupHeads = new Bits.MatchNoBits(searcher.IndexReader.MaxDoc);
            }

            IEnumerable <ISearchGroup <TMutableValue> > topSearchGroups = firstPassCollector.GetTopGroups(groupOffset, fillSortFields);

            if (topSearchGroups == null)
            {
                // LUCENENET specific - optimized empty array creation
                return(new TopGroups <TMutableValue>(Arrays.Empty <SortField>(), Arrays.Empty <SortField>(), 0, 0, Arrays.Empty <GroupDocs <TMutableValue> >(), float.NaN));
            }

            int topNInsideGroup = groupDocsOffset + groupDocsLimit;
            IAbstractSecondPassGroupingCollector <TMutableValue> secondPassCollector;

            secondPassCollector = new FunctionSecondPassGroupingCollector <TMutableValue>(topSearchGroups as IEnumerable <ISearchGroup <TMutableValue> >,
                                                                                          groupSort, sortWithinGroup, topNInsideGroup, includeScores, includeMaxScore, fillSortFields, groupFunction, valueSourceContext)
                                  as IAbstractSecondPassGroupingCollector <TMutableValue>;


            if (cachedCollector != null && cachedCollector.IsCached)
            {
                cachedCollector.Replay(secondPassCollector);
            }
            else
            {
                searcher.Search(query, filter, secondPassCollector);
            }

            if (allGroups)
            {
                return(new TopGroups <TMutableValue>(secondPassCollector.GetTopGroups(groupDocsOffset), matchingGroups.Count));
            }
            else
            {
                return(secondPassCollector.GetTopGroups(groupDocsOffset));
            }
        }
Example #2
0
        protected virtual ITopGroups <TGroupValue> GroupByFieldOrFunction <TGroupValue>(IndexSearcher searcher, Filter filter, Query query, int groupOffset, int groupLimit)
        {
            int topN = groupOffset + groupLimit;
            IAbstractFirstPassGroupingCollector <TGroupValue> firstPassCollector;
            IAbstractAllGroupsCollector <TGroupValue>         allGroupsCollector;
            AbstractAllGroupHeadsCollector allGroupHeadsCollector;

            if (groupFunction != null)
            {
                firstPassCollector = (IAbstractFirstPassGroupingCollector <TGroupValue>) new FunctionFirstPassGroupingCollector(groupFunction, valueSourceContext, groupSort, topN);
                if (allGroups)
                {
                    allGroupsCollector = (IAbstractAllGroupsCollector <TGroupValue>) new FunctionAllGroupsCollector(groupFunction, valueSourceContext);
                }
                else
                {
                    allGroupsCollector = null;
                }
                if (allGroupHeads)
                {
                    allGroupHeadsCollector = new FunctionAllGroupHeadsCollector(groupFunction, valueSourceContext, sortWithinGroup);
                }
                else
                {
                    allGroupHeadsCollector = null;
                }
            }
            else
            {
                firstPassCollector = (IAbstractFirstPassGroupingCollector <TGroupValue>) new TermFirstPassGroupingCollector(groupField, groupSort, topN);
                if (allGroups)
                {
                    allGroupsCollector = (IAbstractAllGroupsCollector <TGroupValue>) new TermAllGroupsCollector(groupField, initialSize);
                }
                else
                {
                    allGroupsCollector = null;
                }
                if (allGroupHeads)
                {
                    allGroupHeadsCollector = TermAllGroupHeadsCollector.Create(groupField, sortWithinGroup, initialSize);
                }
                else
                {
                    allGroupHeadsCollector = null;
                }
            }

            Collector firstRound;

            if (allGroupHeads || allGroups)
            {
                List <Collector> collectors = new List <Collector>();
                // LUCENENET TODO: Make the Collector abstract class into an interface
                // so we can remove the casting here
                collectors.Add((Collector)firstPassCollector);
                if (allGroups)
                {
                    // LUCENENET TODO: Make the Collector abstract class into an interface
                    // so we can remove the casting here
                    collectors.Add((Collector)allGroupsCollector);
                }
                if (allGroupHeads)
                {
                    collectors.Add(allGroupHeadsCollector);
                }
                firstRound = MultiCollector.Wrap(collectors.ToArray(/* new Collector[collectors.size()] */));
            }
            else
            {
                // LUCENENET TODO: Make the Collector abstract class into an interface
                // so we can remove the casting here
                firstRound = (Collector)firstPassCollector;
            }

            CachingCollector cachedCollector = null;

            if (maxCacheRAMMB != null || maxDocsToCache != null)
            {
                if (maxCacheRAMMB != null)
                {
                    cachedCollector = CachingCollector.Create(firstRound, cacheScores, maxCacheRAMMB.Value);
                }
                else
                {
                    cachedCollector = CachingCollector.Create(firstRound, cacheScores, maxDocsToCache.Value);
                }
                searcher.Search(query, filter, cachedCollector);
            }
            else
            {
                searcher.Search(query, filter, firstRound);
            }

            if (allGroups)
            {
                matchingGroups = (IList)allGroupsCollector.Groups;
            }
            else
            {
                matchingGroups = new List <TGroupValue>();
            }
            if (allGroupHeads)
            {
                matchingGroupHeads = allGroupHeadsCollector.RetrieveGroupHeads(searcher.IndexReader.MaxDoc);
            }
            else
            {
                matchingGroupHeads = new Bits_MatchNoBits(searcher.IndexReader.MaxDoc);
            }

            IEnumerable <ISearchGroup <TGroupValue> > topSearchGroups = firstPassCollector.GetTopGroups(groupOffset, fillSortFields);

            if (topSearchGroups == null)
            {
                return(new TopGroups <TGroupValue>(new SortField[0], new SortField[0], 0, 0, new GroupDocs <TGroupValue> [0], float.NaN));
            }

            int topNInsideGroup = groupDocsOffset + groupDocsLimit;
            IAbstractSecondPassGroupingCollector <TGroupValue> secondPassCollector;

            if (groupFunction != null)
            {
                secondPassCollector = new FunctionSecondPassGroupingCollector(topSearchGroups as IEnumerable <ISearchGroup <MutableValue> >,
                                                                              groupSort, sortWithinGroup, topNInsideGroup, includeScores, includeMaxScore, fillSortFields, groupFunction, valueSourceContext)
                                      as IAbstractSecondPassGroupingCollector <TGroupValue>;
            }
            else
            {
                secondPassCollector = new TermSecondPassGroupingCollector(groupField, topSearchGroups as IEnumerable <ISearchGroup <BytesRef> >,
                                                                          groupSort, sortWithinGroup, topNInsideGroup, includeScores, includeMaxScore, fillSortFields)
                                      as IAbstractSecondPassGroupingCollector <TGroupValue>;
            }

            if (cachedCollector != null && cachedCollector.Cached)
            {
                // LUCENENET TODO: Create an ICollector interface that we can inherit our Collector interfaces from
                // so this cast is not necessary. Consider eliminating the Collector abstract class.
                cachedCollector.Replay(secondPassCollector as Collector);
            }
            else
            {
                // LUCENENET TODO: Create an ICollector interface that we can inherit our Collector interfaces from
                // so this cast is not necessary. Consider eliminating the Collector abstract class.
                searcher.Search(query, filter, secondPassCollector as Collector);
            }

            if (allGroups)
            {
                return(new TopGroups <TGroupValue>(secondPassCollector.GetTopGroups(groupDocsOffset), matchingGroups.Count));
            }
            else
            {
                return(secondPassCollector.GetTopGroups(groupDocsOffset));
            }
        }