/// <summary> /// Accumulates groups for the BlockJoinQuery specified by its slot. /// </summary> /// <param name="slot"> Search query's slot </param> /// <param name="offset"> Parent docs offset </param> /// <param name="maxDocsPerGroup"> Upper bound of documents per group number </param> /// <param name="withinGroupOffset"> Offset within each group of child docs </param> /// <param name="withinGroupSort"> Sort criteria within groups </param> /// <param name="fillSortFields"> Specifies whether to add sort fields or not </param> /// <returns> <see cref="ITopGroups{T}"/> for the query specified by slot </returns> /// <exception cref="IOException"> if there is a low-level I/O error </exception> private ITopGroups <int> AccumulateGroups(int slot, int offset, int maxDocsPerGroup, int withinGroupOffset, Sort withinGroupSort, bool fillSortFields) { var groups = new GroupDocs <int> [sortedGroups.Length - offset]; var fakeScorer = new FakeScorer(); int totalGroupedHitCount = 0; //System.out.println("slot=" + slot); for (int groupIdx = offset; groupIdx < sortedGroups.Length; groupIdx++) { OneGroup og = sortedGroups[groupIdx]; int numChildDocs; if (slot == -1 || slot >= og.counts.Length) { numChildDocs = 0; } else { numChildDocs = og.counts[slot]; } // Number of documents in group should be bounded to prevent redundant memory allocation int numDocsInGroup = Math.Max(1, Math.Min(numChildDocs, maxDocsPerGroup)); //System.out.println("parent doc=" + og.doc + " numChildDocs=" + numChildDocs + " maxDocsPG=" + maxDocsPerGroup); // At this point we hold all docs w/ in each group, unsorted; we now sort them: ICollector collector; if (withinGroupSort == null) { //System.out.println("sort by score"); // Sort by score if (!trackScores) { throw new ArgumentException("cannot sort by relevance within group: trackScores=false"); } collector = TopScoreDocCollector.Create(numDocsInGroup, true); } else { // Sort by fields collector = TopFieldCollector.Create(withinGroupSort, numDocsInGroup, fillSortFields, trackScores, trackMaxScore, true); } collector.SetScorer(fakeScorer); collector.SetNextReader(og.readerContext); for (int docIdx = 0; docIdx < numChildDocs; docIdx++) { //System.out.println("docIDX=" + docIDX + " vs " + og.docs[slot].length); int doc = og.docs[slot][docIdx]; fakeScorer.doc = doc; if (trackScores) { fakeScorer._score = og.scores[slot][docIdx]; } collector.Collect(doc); } totalGroupedHitCount += numChildDocs; object[] groupSortValues; if (fillSortFields) { groupSortValues = new object[comparers.Length]; for (int sortFieldIdx = 0; sortFieldIdx < comparers.Length; sortFieldIdx++) { groupSortValues[sortFieldIdx] = comparers[sortFieldIdx][og.Slot]; } } else { groupSortValues = null; } TopDocs topDocs; if (withinGroupSort == null) { var tempCollector = (TopScoreDocCollector)collector; topDocs = tempCollector.GetTopDocs(withinGroupOffset, numDocsInGroup); } else { var tempCollector = (TopFieldCollector)collector; topDocs = tempCollector.GetTopDocs(withinGroupOffset, numDocsInGroup); } groups[groupIdx - offset] = new GroupDocs <int>(og.Score, topDocs.MaxScore, numChildDocs, topDocs.ScoreDocs, og.Doc, groupSortValues); } return(new TopGroups <int>(new TopGroups <int>(sort.GetSort(), withinGroupSort == null ? null : withinGroupSort.GetSort(), 0, totalGroupedHitCount, groups, maxScore), totalHitCount)); }
/// <summary> /// Accumulates groups for the BlockJoinQuery specified by its slot. /// </summary> /// <param name="slot"> Search query's slot </param> /// <param name="offset"> Parent docs offset </param> /// <param name="maxDocsPerGroup"> Upper bound of documents per group number </param> /// <param name="withinGroupOffset"> Offset within each group of child docs </param> /// <param name="withinGroupSort"> Sort criteria within groups </param> /// <param name="fillSortFields"> Specifies whether to add sort fields or not </param> /// <returns> TopGroups for the query specified by slot </returns> /// <exception cref="IOException"> if there is a low-level I/O error </exception> private TopGroups<int> AccumulateGroups(int slot, int offset, int maxDocsPerGroup, int withinGroupOffset, Sort withinGroupSort, bool fillSortFields) { var groups = new GroupDocs<int>[sortedGroups.Length - offset]; var fakeScorer = new FakeScorer(); int totalGroupedHitCount = 0; //System.out.println("slot=" + slot); for (int groupIdx = offset; groupIdx < sortedGroups.Length; groupIdx++) { OneGroup og = sortedGroups[groupIdx]; int numChildDocs; if (slot == -1 || slot >= og.counts.Length) { numChildDocs = 0; } else { numChildDocs = og.counts[slot]; } // Number of documents in group should be bounded to prevent redundant memory allocation int numDocsInGroup = Math.Max(1, Math.Min(numChildDocs, maxDocsPerGroup)); //System.out.println("parent doc=" + og.doc + " numChildDocs=" + numChildDocs + " maxDocsPG=" + maxDocsPerGroup); // At this point we hold all docs w/ in each group, unsorted; we now sort them: Collector collector; if (withinGroupSort == null) { //System.out.println("sort by score"); // Sort by score if (!trackScores) { throw new ArgumentException("cannot sort by relevance within group: trackScores=false"); } collector = TopScoreDocCollector.Create(numDocsInGroup, true); } else { // Sort by fields collector = TopFieldCollector.Create(withinGroupSort, numDocsInGroup, fillSortFields, trackScores, trackMaxScore, true); } collector.Scorer = fakeScorer; collector.NextReader = og.readerContext; for (int docIdx = 0; docIdx < numChildDocs; docIdx++) { //System.out.println("docIDX=" + docIDX + " vs " + og.docs[slot].length); int doc = og.docs[slot][docIdx]; fakeScorer.doc = doc; if (trackScores) { fakeScorer._score = og.scores[slot][docIdx]; } collector.Collect(doc); } totalGroupedHitCount += numChildDocs; object[] groupSortValues; if (fillSortFields) { groupSortValues = new object[comparators.Length]; for (int sortFieldIdx = 0; sortFieldIdx < comparators.Length; sortFieldIdx++) { groupSortValues[sortFieldIdx] = comparators[sortFieldIdx].Value(og.Slot); } } else { groupSortValues = null; } TopDocs topDocs; if (withinGroupSort == null) { var tempCollector = (TopScoreDocCollector) collector; topDocs = tempCollector.TopDocs(withinGroupOffset, numDocsInGroup); } else { var tempCollector = (TopFieldCollector) collector; topDocs = tempCollector.TopDocs(withinGroupOffset, numDocsInGroup); } groups[groupIdx - offset] = new GroupDocs<int>(og.Score, topDocs.MaxScore, numChildDocs, topDocs.ScoreDocs, og.Doc, groupSortValues); } return new TopGroups<int>(new TopGroups<int>(sort.GetSort(), withinGroupSort == null ? null : withinGroupSort.GetSort(), 0, totalGroupedHitCount, groups, maxScore), totalHitCount); }