TestBooleanMinShouldMatchpublic class TestBooleanMinShouldMatch extends TestCase Test that BooleanQuery.setMinimumNumberShouldMatch works. |
Fields Summary |
---|
public Directory | index | public IndexReader | r | public IndexSearcher | s |
Methods Summary |
---|
protected void | printHits(java.lang.String test, org.apache.lucene.search.Hits h)
System.err.println("------- " + test + " -------");
DecimalFormat f = new DecimalFormat("0.000000");
for (int i = 0; i < h.length(); i++) {
Document d = h.doc(i);
float score = h.score(i);
System.err.println("#" + i + ": " + f.format(score) + " - " +
d.get("id") + " - " + d.get("data"));
}
| public void | setUp()
String[] data = new String [] {
"A 1 2 3 4 5 6",
"Z 4 5 6",
null,
"B 2 4 5 6",
"Y 3 5 6",
null,
"C 3 6",
"X 4 5 6"
};
index = new RAMDirectory();
IndexWriter writer = new IndexWriter(index,
new WhitespaceAnalyzer(),
true);
for (int i = 0; i < data.length; i++) {
Document doc = new Document();
doc.add(Field.Keyword("id",String.valueOf(i)));
doc.add(Field.Keyword("all","all"));
if (null != data[i]) {
doc.add(Field.Text("data",data[i]));
}
writer.addDocument(doc);
}
writer.optimize();
writer.close();
r = IndexReader.open(index);
s = new IndexSearcher(r);
//System.out.println("Set up " + getName());
| public void | testAllOptional()
BooleanQuery q = new BooleanQuery();
for (int i = 1; i <=4; i++) {
q.add(new TermQuery(new Term("data",""+i)), false, false);
}
q.setMinimumNumberShouldMatch(2); // match at least two of 4
verifyNrHits(q, 2);
| public void | testMinEqualToNumOptional()
/* two required, two optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all" )), false, false);
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "3" )), true, false);
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.setMinimumNumberShouldMatch(2); // 2 of 2 optional
verifyNrHits(q, 1);
| public void | testMinHigherThenNumOptional()
/* two required, two prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all")), true, false);
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.add(new TermQuery(new Term("data", "C" )), false, true );
q.setMinimumNumberShouldMatch(90); // 90 of 4 optional ?!?!?!
verifyNrHits(q, 0);
| public void | testNoOptionalButMin()
/* two required, no optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all" )), true, false);
q.add(new TermQuery(new Term("data", "2" )), true, false);
q.setMinimumNumberShouldMatch(1); // 1 of 0 optional
verifyNrHits(q, 0);
| public void | testOneOptionalEqualToMin()
/* two required, one optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all" )), true, false);
q.add(new TermQuery(new Term("data", "3" )), false, false);
q.add(new TermQuery(new Term("data", "2" )), true, false);
q.setMinimumNumberShouldMatch(1); // 1 of 1 optional
verifyNrHits(q, 1);
| public void | testOneProhibAndSomeOptional()
/* one prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.setMinimumNumberShouldMatch(2); // 2 of 3 optional
verifyNrHits(q, 1);
| public void | testOneReqAndSomeOptional()
/* one required, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, false);
q.setMinimumNumberShouldMatch(2); // 2 of 3 optional
verifyNrHits(q, 5);
| public void | testOneReqOneProhibAndSomeOptional()
/* one required, one prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.setMinimumNumberShouldMatch(3); // 3 of 4 optional
verifyNrHits(q, 1);
| public void | testOneReqSomeProhibAndSomeOptional()
/* one required, two prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.add(new TermQuery(new Term("data", "C" )), false, true );
q.setMinimumNumberShouldMatch(3); // 3 of 4 optional
verifyNrHits(q, 1);
| public void | testRandomQueries()
final Random rnd = new Random(0);
String field="data";
String[] vals = {"1","2","3","4","5","6","A","Z","B","Y","Z","X","foo"};
int maxLev=4;
// callback object to set a random setMinimumNumberShouldMatch
TestBoolean2.Callback minNrCB = new TestBoolean2.Callback() {
public void postCreate(BooleanQuery q) {
BooleanClause[] c =q.getClauses();
int opt=0;
for (int i=0; i<c.length;i++) {
if (c[i].getOccur() == BooleanClause.Occur.SHOULD) opt++;
}
q.setMinimumNumberShouldMatch(rnd.nextInt(opt+2));
}
};
int tot=0;
// increase number of iterations for more complete testing
for (int i=0; i<1000; i++) {
int lev = rnd.nextInt(maxLev);
BooleanQuery q1 = TestBoolean2.randBoolQuery(new Random(i), lev, field, vals, null);
// BooleanQuery q2 = TestBoolean2.randBoolQuery(new Random(i), lev, field, vals, minNrCB);
BooleanQuery q2 = TestBoolean2.randBoolQuery(new Random(i), lev, field, vals, null);
// only set minimumNumberShouldMatch on the top level query since setting
// at a lower level can change the score.
minNrCB.postCreate(q2);
// Can't use Hits because normalized scores will mess things
// up. The non-sorting version of search() that returns TopDocs
// will not normalize scores.
TopDocs top1 = s.search(q1,null,100);
TopDocs top2 = s.search(q2,null,100);
tot+=top2.totalHits;
// The constrained query
// should be a superset to the unconstrained query.
if (top2.totalHits > top1.totalHits) {
TestCase.fail("Constrained results not a subset:\n"
+ CheckHits.topdocsString(top1,0,0)
+ CheckHits.topdocsString(top2,0,0)
+ "for query:" + q2.toString());
}
for (int hit=0; hit<top2.totalHits; hit++) {
int id = top2.scoreDocs[hit].doc;
float score = top2.scoreDocs[hit].score;
boolean found=false;
// find this doc in other hits
for (int other=0; other<top1.totalHits; other++) {
if (top1.scoreDocs[other].doc == id) {
found=true;
float otherScore = top1.scoreDocs[other].score;
// check if scores match
if (Math.abs(otherScore-score)>1.0e-6f) {
TestCase.fail("Doc " + id + " scores don't match\n"
+ CheckHits.topdocsString(top1,0,0)
+ CheckHits.topdocsString(top2,0,0)
+ "for query:" + q2.toString());
}
}
}
// check if subset
if (!found) TestCase.fail("Doc " + id + " not found\n"
+ CheckHits.topdocsString(top1,0,0)
+ CheckHits.topdocsString(top2,0,0)
+ "for query:" + q2.toString());
}
}
// System.out.println("Total hits:"+tot);
| public void | testSomeProhibAndSomeOptional()
/* two prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "C" )), false, true );
q.setMinimumNumberShouldMatch(2); // 2 of 3 optional
verifyNrHits(q, 1);
| public void | testSomeReqAndSomeOptional()
/* two required, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all" )), true, false);
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, false);
q.setMinimumNumberShouldMatch(2); // 2 of 3 optional
verifyNrHits(q, 5);
| public void | testSomeReqOneProhibAndSomeOptional()
/* two required, one prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all")), true, false);
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.setMinimumNumberShouldMatch(3); // 3 of 4 optional
verifyNrHits(q, 1);
| public void | testSomeReqSomeProhibAndSomeOptional()
/* two required, two prohibited, some optional */
BooleanQuery q = new BooleanQuery();
q.add(new TermQuery(new Term("all", "all")), true, false);
q.add(new TermQuery(new Term("data", "6" )), true, false);
q.add(new TermQuery(new Term("data", "5" )), false, false);
q.add(new TermQuery(new Term("data", "4" )), false, false);
q.add(new TermQuery(new Term("data", "3" )), false, true );
q.add(new TermQuery(new Term("data", "2" )), false, false);
q.add(new TermQuery(new Term("data", "1" )), false, false);
q.add(new TermQuery(new Term("data", "C" )), false, true );
q.setMinimumNumberShouldMatch(3); // 3 of 4 optional
verifyNrHits(q, 1);
| public void | verifyNrHits(org.apache.lucene.search.Query q, int expected)
Hits h = s.search(q);
if (expected != h.length()) {
printHits(getName(), h);
}
assertEquals("result count", expected, h.length());
|
|