Merged revision(s) 1208375 from lucene/dev/branches/branch_3x:

LUCENE-3609: Fix regression in BooleanFilter, introduced in Lucene 3.5, to correctly handle minShouldMatch behaviour of previous versions

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1208381 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2011-11-30 11:08:45 +00:00
parent 21b7c5bbee
commit 277c4a1a5d
3 changed files with 36 additions and 0 deletions

View File

@ -92,6 +92,10 @@ Bug Fixes
assert if such a parent doc was the first doc in the segment).
(Shay Banon, Mike McCandless)
* LUCENE-3609: Fix regression in BooleanFilter, introduced in Lucene 3.5,
to correctly handle minShouldMatch behaviour of previous versions.
(Shay Banon, Uwe Schindler)
Documentation
* LUCENE-3599: Javadocs for DistanceUtils.haversine() were incorrectly

View File

@ -54,8 +54,10 @@ public class BooleanFilter extends Filter implements Iterable<FilterClause> {
FixedBitSet res = null;
final IndexReader reader = context.reader;
boolean hasShouldClauses = false;
for (final FilterClause fc : clauses) {
if (fc.getOccur() == Occur.SHOULD) {
hasShouldClauses = true;
final DocIdSetIterator disi = getDISI(fc.getFilter(), context);
if (disi == null) continue;
if (res == null) {
@ -64,10 +66,13 @@ public class BooleanFilter extends Filter implements Iterable<FilterClause> {
res.or(disi);
}
}
if (hasShouldClauses && res == null)
return DocIdSet.EMPTY_DOCIDSET;
for (final FilterClause fc : clauses) {
if (fc.getOccur() == Occur.MUST_NOT) {
if (res == null) {
assert !hasShouldClauses;
res = new FixedBitSet(reader.maxDoc());
res.set(0, reader.maxDoc()); // NOTE: may set bits on deleted docs
}

View File

@ -36,6 +36,7 @@ import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.LuceneTestCase;
import java.io.IOException;
@ -92,6 +93,15 @@ public class BooleanFilterTest extends LuceneTestCase {
return new QueryWrapperFilter(new TermQuery(new Term(field, text)));
}
private Filter getEmptyFilter() {
return new Filter() {
@Override
public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) {
return new FixedBitSet(context.reader.maxDoc());
}
};
}
private Filter getNullDISFilter() {
return new Filter() {
@Override
@ -309,4 +319,21 @@ public class BooleanFilterTest extends LuceneTestCase {
booleanFilter.add(getNullDISIFilter(), Occur.MUST_NOT);
tstFilterCard("A single MUST_NOT filter that returns a null DIS should be invisible", 5, booleanFilter);
}
public void testNonMatchingShouldsAndMusts() throws Exception {
BooleanFilter booleanFilter = new BooleanFilter();
booleanFilter.add(getEmptyFilter(), Occur.SHOULD);
booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
tstFilterCard(">0 shoulds with no matches should return no docs", 0, booleanFilter);
booleanFilter = new BooleanFilter();
booleanFilter.add(getNullDISFilter(), Occur.SHOULD);
booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
tstFilterCard(">0 shoulds with no matches should return no docs", 0, booleanFilter);
booleanFilter = new BooleanFilter();
booleanFilter.add(getNullDISIFilter(), Occur.SHOULD);
booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
tstFilterCard(">0 shoulds with no matches should return no docs", 0, booleanFilter);
}
}