Skip to content

Commit 2df7908

Browse files
committed
handle missing value
1 parent 2be09bb commit 2df7908

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

lucene/core/src/java/org/apache/lucene/search/comparators/NumericComparator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,11 @@ int docCount() {
374374
*/
375375
void postInitializeCompetitiveIterator() throws IOException {
376376
if (queueFull) {
377+
// if some documents have missing points, then check that missing values prohibits
378+
// optimization
379+
if (docCount() < maxDoc && isMissingValueCompetitive()) {
380+
return;
381+
}
377382
long bottom = leafComparator.bottomAsComparableLong();
378383
long minValue = sortableBytesToLong(pointValues.getMinPackedValue());
379384
long maxValue = sortableBytesToLong(pointValues.getMaxPackedValue());
@@ -532,6 +537,11 @@ int docCount() {
532537
*/
533538
void postInitializeCompetitiveIterator() {
534539
if (queueFull) {
540+
// if some documents have missing doc values, check that missing values prohibits
541+
// optimization
542+
if (docCount() < maxDoc && isMissingValueCompetitive()) {
543+
return;
544+
}
535545
long bottom = leafComparator.bottomAsComparableLong();
536546
if (reverse == false && bottom < skipper.minValue()) {
537547
competitiveIterator.update(DocIdSetIterator.empty());

lucene/core/src/test/org/apache/lucene/search/comparators/TestNumericComparator.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
import org.apache.lucene.index.IndexWriterConfig;
2929
import org.apache.lucene.index.LeafReaderContext;
3030
import org.apache.lucene.search.DocIdSetIterator;
31+
import org.apache.lucene.search.FieldDoc;
32+
import org.apache.lucene.search.MatchAllDocsQuery;
3133
import org.apache.lucene.search.Pruning;
34+
import org.apache.lucene.search.Sort;
3235
import org.apache.lucene.search.SortField;
3336
import org.apache.lucene.tests.util.LuceneTestCase;
3437

@@ -105,6 +108,61 @@ public void testEmptyCompetitiveIteratorOptimization() throws Exception {
105108
}
106109
}
107110

111+
public void testEmptyCompetitiveIteratorOptimizationWithMissingValue() throws Exception {
112+
final int numDocs = atLeast(1000);
113+
try (var dir = newDirectory()) {
114+
try (var writer =
115+
new IndexWriter(dir, new IndexWriterConfig().setMergePolicy(newLogMergePolicy()))) {
116+
// index docs without missing values:
117+
for (int i = 0; i < numDocs; i++) {
118+
var doc = new Document();
119+
120+
doc.add(NumericDocValuesField.indexedField("long_field_1", i));
121+
doc.add(new LongPoint("long_field_2", i));
122+
doc.add(new NumericDocValuesField("long_field_2", i));
123+
124+
writer.addDocument(doc);
125+
if (i % 100 == 0) {
126+
writer.flush();
127+
}
128+
}
129+
130+
// Index one doc with without long_field_1 and long_field_2 fields
131+
var doc = new Document();
132+
doc.add(new NumericDocValuesField("another_field", numDocs));
133+
writer.addDocument(doc);
134+
writer.flush();
135+
136+
try (var reader = DirectoryReader.open(writer)) {
137+
var indexSearcher = newSearcher(reader);
138+
indexSearcher.setQueryCache(null);
139+
{
140+
var sortField = new SortField("long_field_1", SortField.Type.LONG, false);
141+
sortField.setMissingValue(Long.MIN_VALUE);
142+
var topDocs = indexSearcher.search(new MatchAllDocsQuery(), 3, new Sort(sortField));
143+
assertEquals(numDocs, topDocs.scoreDocs[0].doc);
144+
assertEquals(Long.MIN_VALUE, ((FieldDoc) topDocs.scoreDocs[0]).fields[0]);
145+
assertEquals(0, topDocs.scoreDocs[1].doc);
146+
assertEquals(0L, ((FieldDoc) topDocs.scoreDocs[1]).fields[0]);
147+
assertEquals(1, topDocs.scoreDocs[2].doc);
148+
assertEquals(1L, ((FieldDoc) topDocs.scoreDocs[2]).fields[0]);
149+
}
150+
{
151+
var sortField = new SortField("long_field_2", SortField.Type.LONG, false);
152+
sortField.setMissingValue(Long.MIN_VALUE);
153+
var topDocs = indexSearcher.search(new MatchAllDocsQuery(), 3, new Sort(sortField));
154+
assertEquals(numDocs, topDocs.scoreDocs[0].doc);
155+
assertEquals(Long.MIN_VALUE, ((FieldDoc) topDocs.scoreDocs[0]).fields[0]);
156+
assertEquals(0, topDocs.scoreDocs[1].doc);
157+
assertEquals(0L, ((FieldDoc) topDocs.scoreDocs[1]).fields[0]);
158+
assertEquals(1, topDocs.scoreDocs[2].doc);
159+
assertEquals(1L, ((FieldDoc) topDocs.scoreDocs[2]).fields[0]);
160+
}
161+
}
162+
}
163+
}
164+
}
165+
108166
private static void assertLongField(
109167
String fieldName, boolean reverse, int bottom, LeafReaderContext leafContext)
110168
throws IOException {

0 commit comments

Comments
 (0)