Skip to content

Commit ba1b050

Browse files
authored
Fix GroupingSearch.TotalGroupCount null when groupOffset exceeds group count, apache#1362 (apache#1363)
1 parent 0a16c76 commit ba1b050

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

src/Lucene.Net.Grouping/GroupingSearch.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,10 @@ public override TopGroups<T> Search(IndexSearcher searcher,
450450
if (topSearchGroups is null)
451451
{
452452
// LUCENENET specific - optimized empty array creation
453-
return new TopGroups<T>(Array.Empty<SortField>(), Array.Empty<SortField>(), 0, 0, Array.Empty<GroupDocs<T>>(), float.NaN);
453+
var emptyResult = new TopGroups<T>(Array.Empty<SortField>(), Array.Empty<SortField>(), 0, 0, Array.Empty<GroupDocs<T>>(), float.NaN);
454+
return AllGroups
455+
? new TopGroups<T>(emptyResult, MatchingGroups.Count)
456+
: emptyResult;
454457
}
455458

456459
int topNInsideGroup = GroupDocsOffset + GroupDocsLimit;

src/Lucene.Net.Tests.Grouping/GroupingSearchTest.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,48 @@ public virtual void TestSetAllGroups()
335335
dir.Dispose();
336336
}
337337

338+
// LUCENENET specific - regression test for #1362
339+
[Test]
340+
[LuceneNetSpecific]
341+
public virtual void TestSetAllGroups_GroupOffsetBeyondGroupCount_TotalGroupCountNotNull()
342+
{
343+
// When groupOffset exceeds the number of groups, topSearchGroups is null and
344+
// the early return path must still populate TotalGroupCount from allGroupsCollector.
345+
using Directory dir = NewDirectory();
346+
RandomIndexWriter w = new RandomIndexWriter(
347+
Random,
348+
dir,
349+
NewIndexWriterConfig(TEST_VERSION_CURRENT,
350+
new MockAnalyzer(Random)).SetMergePolicy(NewLogMergePolicy()));
351+
352+
// Index 2 documents in the same group.
353+
Document doc = new Document();
354+
doc.Add(new StringField("group", "foo", Field.Store.NO));
355+
doc.Add(new TextField("content", "hello world", Field.Store.NO));
356+
w.AddDocument(doc);
357+
358+
doc = new Document();
359+
doc.Add(new StringField("group", "foo", Field.Store.NO));
360+
doc.Add(new TextField("content", "hello world", Field.Store.NO));
361+
w.AddDocument(doc);
362+
363+
IndexSearcher indexSearcher = NewSearcher(w.GetReader());
364+
w.Dispose();
365+
366+
// groupOffset=5 exceeds the 1 matching group, so topSearchGroups will be null
367+
// in the first-pass collector. With SetAllGroups(true), TotalGroupCount must
368+
// still be set to the real group count (1), not left null.
369+
var gs = GroupingSearch.ByField("group");
370+
gs.SetAllGroups(true);
371+
TopGroups<BytesRef> groups = gs.Search(indexSearcher, null, new TermQuery(new Index.Term("content", "hello")), 5, 10);
372+
373+
assertNotNull("TotalGroupCount must not be null when SetAllGroups(true) and groupOffset exceeds group count", groups.TotalGroupCount);
374+
assertEquals(1, groups.TotalGroupCount.GetValueOrDefault());
375+
assertEquals(0, groups.Groups.Length);
376+
377+
indexSearcher.IndexReader.Dispose();
378+
}
379+
338380
// LUCENENET specific - tests for the CancellationToken support
339381
// added to GroupingSearch. See #922.
340382

0 commit comments

Comments
 (0)