//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)); } }
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)); } }