LUCENE-9462: Fields without positions should still return MatchIterator. (#1749)

This commit is contained in:
Dawid Weiss 2020-08-14 11:45:32 +02:00 committed by GitHub
parent 216aec03a6
commit 6244383e0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 10 deletions

View File

@ -12,7 +12,7 @@ System Requirements
API Changes
* LUCENE-8474: RAMDirectory and associated deprecated classes have been
* LUCENE-8474: RAMDirectory and associated deprecated classes have been
removed. (Dawid Weiss)
* LUCENE-3041: The deprecated Weight#extractTerms() method has been
@ -58,6 +58,9 @@ API Changes
* LUCENE-9340: SimpleBindings#add(SortField) has been removed. (Alan Woodward)
* LUCENE-9462: Fields without positions should still return MatchIterator.
(Alan Woodward, Dawid Weiss)
Improvements
* LUCENE-9370: RegExp query is no longer lenient about inappropriate backslashes and

View File

@ -202,7 +202,8 @@ final class DisjunctionMatchesIterator implements MatchesIterator {
@Override
public boolean next() throws IOException {
if (started == false) {
return started = true;
started = true;
return queue.size() > 0;
}
if (queue.top().next() == false) {
queue.pop();

View File

@ -208,9 +208,6 @@ final class MultiTermQueryConstantScoreWrapper<Q extends MultiTermQuery> extends
if (terms == null) {
return null;
}
if (terms.hasPositions() == false) {
return super.matches(context, doc);
}
return MatchesUtils.forField(query.field, () -> DisjunctionMatchesIterator.fromTermsEnum(context, doc, query, query.field, query.getTermsEnum(terms)));
}

View File

@ -226,7 +226,7 @@ public final class SynonymQuery extends Query {
public Matches matches(LeafReaderContext context, int doc) throws IOException {
String field = terms[0].term.field();
Terms indexTerms = context.reader().terms(field);
if (indexTerms == null || indexTerms.hasPositions() == false) {
if (indexTerms == null) {
return super.matches(context, doc);
}
List<Term> termList = Arrays.stream(terms)

View File

@ -80,9 +80,6 @@ public class TermQuery extends Query {
if (te == null) {
return null;
}
if (context.reader().terms(term.field()).hasPositions() == false) {
return super.matches(context, doc);
}
return MatchesUtils.forField(term.field(), () -> {
PostingsEnum pe = te.postings(null, PostingsEnum.OFFSETS);
if (pe.advance(doc) != doc) {

View File

@ -21,9 +21,11 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
@ -184,7 +186,11 @@ public class TestMatchesIterator extends LuceneTestCase {
Matches matches = w.matches(ctx, doc);
if (expected[i]) {
MatchesIterator mi = matches.getMatches(field);
assertNull(mi);
assertTrue(mi.next());
assertEquals(-1, mi.startPosition());
while (mi.next()) {
assertEquals(-1, mi.startPosition());
}
}
else {
assertNull(matches);
@ -754,6 +760,91 @@ public class TestMatchesIterator extends LuceneTestCase {
}
}
public void testFromSubIteratorsMethod() throws IOException {
class CountIterator implements MatchesIterator {
private int count;
private int max;
CountIterator(int count) {
this.count = count;
this.max = count;
}
@Override
public boolean next() throws IOException {
if (count == 0) {
return false;
} else {
count--;
return true;
}
}
@Override
public int startPosition() {
return max - count;
}
@Override
public int endPosition() {
return max - count;
}
@Override
public int startOffset() throws IOException {
throw new AssertionError();
}
@Override
public int endOffset() throws IOException {
throw new AssertionError();
}
@Override
public MatchesIterator getSubMatches() throws IOException {
throw new AssertionError();
}
@Override
public Query getQuery() {
throw new AssertionError();
}
}
int [][] checks = {
{ 0 },
{ 1 },
{ 0, 0 },
{ 0, 1 },
{ 1, 0 },
{ 1, 1 },
{ 0, 0, 0 },
{ 0, 0, 1 },
{ 0, 1, 0 },
{ 1, 0, 0 },
{ 1, 0, 1 },
{ 1, 1, 0 },
{ 1, 1, 1 },
};
for (int[] counts : checks) {
List<MatchesIterator> its = IntStream.of(counts)
.mapToObj(CountIterator::new)
.collect(Collectors.toList());
int expectedCount = IntStream.of(counts).sum();
MatchesIterator merged = DisjunctionMatchesIterator.fromSubIterators(its);
int actualCount = 0;
while (merged.next()) {
actualCount++;
}
assertEquals("Sub-iterator count is not right for: "
+ Arrays.toString(counts), expectedCount, actualCount);
}
}
private static class SeekCountingLeafReader extends FilterLeafReader {
int seeks = 0;