Index: test/org/apache/lucene/search/TestBooleanMinShouldMatch.java =================================================================== --- test/org/apache/lucene/search/TestBooleanMinShouldMatch.java (revision 832972) +++ test/org/apache/lucene/search/TestBooleanMinShouldMatch.java Sat Nov 14 20:46:53 EST 2009 @@ -19,7 +19,6 @@ import junit.framework.TestCase; -import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.analysis.WhitespaceAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; @@ -28,25 +27,27 @@ import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.LuceneTestCase; import java.text.DecimalFormat; import java.util.Random; -/** Test that BooleanQuery.setMinimumNumberShouldMatch works. +/** + * Test that BooleanQuery.setMinimumNumberShouldMatch works. */ public class TestBooleanMinShouldMatch extends LuceneTestCase { - public Directory index; - public IndexReader r; - public IndexSearcher s; + public Directory index; + public IndexReader r; + public IndexSearcher s; - @Override - public void setUp() throws Exception { - super.setUp(); + @Override + public void setUp() throws Exception { + super.setUp(); - String[] data = new String [] { + String[] data = new String[]{ "A 1 2 3 4 5 6", "Z 4 5 6", null, @@ -55,337 +56,337 @@ null, "C 3 6", "X 4 5 6" - }; + }; - index = new RAMDirectory(); - IndexWriter writer = new IndexWriter(index, - new WhitespaceAnalyzer(), - true, IndexWriter.MaxFieldLength.LIMITED); + index = new RAMDirectory(); + IndexWriter writer = new IndexWriter(index, + new WhitespaceAnalyzer(), + true, IndexWriter.MaxFieldLength.LIMITED); - for (int i = 0; i < data.length; i++) { - Document doc = new Document(); - doc.add(new Field("id", String.valueOf(i), Field.Store.YES, Field.Index.NOT_ANALYZED));//Field.Keyword("id",String.valueOf(i))); - doc.add(new Field("all", "all", Field.Store.YES, Field.Index.NOT_ANALYZED));//Field.Keyword("all","all")); - if (null != data[i]) { - doc.add(new Field("data", data[i], Field.Store.YES, Field.Index.ANALYZED));//Field.Text("data",data[i])); - } - writer.addDocument(doc); - } + for (int i = 0; i < data.length; i++) { + Document doc = new Document(); + doc.add(new Field("id", String.valueOf(i), Field.Store.YES, Field.Index.NOT_ANALYZED));//Field.Keyword("id",String.valueOf(i))); + doc.add(new Field("all", "all", Field.Store.YES, Field.Index.NOT_ANALYZED));//Field.Keyword("all","all")); + if (null != data[i]) { + doc.add(new Field("data", data[i], Field.Store.YES, Field.Index.ANALYZED));//Field.Text("data",data[i])); + } + writer.addDocument(doc); + } - writer.optimize(); - writer.close(); + writer.optimize(); + writer.close(); - r = IndexReader.open(index, true); - s = new IndexSearcher(r); + r = IndexReader.open(index, true); + s = new IndexSearcher(r); //System.out.println("Set up " + getName()); - } + } - public void verifyNrHits(Query q, int expected) throws Exception { - ScoreDoc[] h = s.search(q, null, 1000).scoreDocs; - if (expected != h.length) { - printHits(getName(), h, s); - } - assertEquals("result count", expected, h.length); + public void verifyNrHits(Query q, int expected) throws Exception { + ScoreDoc[] h = s.search(q, null, 1000).scoreDocs; + if (expected != h.length) { + printHits(getName(), h, s); + } + assertEquals("result count", expected, h.length); - QueryUtils.check(q,s); + QueryUtils.check(q, s); - } + } - public void testAllOptional() throws Exception { + public void testAllOptional() throws Exception { - BooleanQuery q = new BooleanQuery(); + BooleanQuery q = new BooleanQuery(); - for (int i = 1; i <=4; i++) { + for (int i = 1; i <= 4; i++) { - q.add(new TermQuery(new Term("data",""+i)), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "" + i)), BooleanClause.Occur.SHOULD);//false, false); - } - q.setMinimumNumberShouldMatch(2); // match at least two of 4 - verifyNrHits(q, 2); - } + } + q.setMinimumNumberShouldMatch(2); // match at least two of 4 + verifyNrHits(q, 2); + } - public void testOneReqAndSomeOptional() throws Exception { + public void testOneReqAndSomeOptional() throws Exception { - /* one required, some optional */ - BooleanQuery q = new BooleanQuery(); + /* one required, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.SHOULD);//false, false); - q.setMinimumNumberShouldMatch(2); // 2 of 3 optional + q.setMinimumNumberShouldMatch(2); // 2 of 3 optional - verifyNrHits(q, 5); - } + verifyNrHits(q, 5); + } - public void testSomeReqAndSomeOptional() throws Exception { + public void testSomeReqAndSomeOptional() throws Exception { - /* two required, some optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.SHOULD);//false, false); - q.setMinimumNumberShouldMatch(2); // 2 of 3 optional + q.setMinimumNumberShouldMatch(2); // 2 of 3 optional - verifyNrHits(q, 5); - } + verifyNrHits(q, 5); + } - public void testOneProhibAndSomeOptional() throws Exception { + public void testOneProhibAndSomeOptional() throws Exception { - /* one prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* one prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.setMinimumNumberShouldMatch(2); // 2 of 3 optional + q.setMinimumNumberShouldMatch(2); // 2 of 3 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testSomeProhibAndSomeOptional() throws Exception { + public void testSomeProhibAndSomeOptional() throws Exception { - /* two prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* two prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "C" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "C")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.setMinimumNumberShouldMatch(2); // 2 of 3 optional + q.setMinimumNumberShouldMatch(2); // 2 of 3 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testOneReqOneProhibAndSomeOptional() throws Exception { + public void testOneReqOneProhibAndSomeOptional() throws Exception { - /* one required, one prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* one required, one prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);// true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);// true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.setMinimumNumberShouldMatch(3); // 3 of 4 optional + q.setMinimumNumberShouldMatch(3); // 3 of 4 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testSomeReqOneProhibAndSomeOptional() throws Exception { + public void testSomeReqOneProhibAndSomeOptional() throws Exception { - /* two required, one prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, one prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.setMinimumNumberShouldMatch(3); // 3 of 4 optional + q.setMinimumNumberShouldMatch(3); // 3 of 4 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testOneReqSomeProhibAndSomeOptional() throws Exception { + public void testOneReqSomeProhibAndSomeOptional() throws Exception { - /* one required, two prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* one required, two prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "C" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "C")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.setMinimumNumberShouldMatch(3); // 3 of 4 optional + q.setMinimumNumberShouldMatch(3); // 3 of 4 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testSomeReqSomeProhibAndSomeOptional() throws Exception { + public void testSomeReqSomeProhibAndSomeOptional() throws Exception { - /* two required, two prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, two prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "C" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "C")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.setMinimumNumberShouldMatch(3); // 3 of 4 optional + q.setMinimumNumberShouldMatch(3); // 3 of 4 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testMinHigherThenNumOptional() throws Exception { + public void testMinHigherThenNumOptional() throws Exception { - /* two required, two prohibited, some optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, two prohibited, some optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "5" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "5")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "4" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "4")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "1" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "C" )), BooleanClause.Occur.MUST_NOT);//false, true ); + q.add(new TermQuery(new Term("data", "C")), BooleanClause.Occur.MUST_NOT);//false, true ); - q.setMinimumNumberShouldMatch(90); // 90 of 4 optional ?!?!?! + q.setMinimumNumberShouldMatch(90); // 90 of 4 optional ?!?!?! - verifyNrHits(q, 0); - } + verifyNrHits(q, 0); + } - public void testMinEqualToNumOptional() throws Exception { + public void testMinEqualToNumOptional() throws Exception { - /* two required, two optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, two optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "6" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "6")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.SHOULD);//false, false); - q.setMinimumNumberShouldMatch(2); // 2 of 2 optional + q.setMinimumNumberShouldMatch(2); // 2 of 2 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testOneOptionalEqualToMin() throws Exception { + public void testOneOptionalEqualToMin() throws Exception { - /* two required, one optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, one optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "3" )), BooleanClause.Occur.SHOULD);//false, false); + q.add(new TermQuery(new Term("data", "3")), BooleanClause.Occur.SHOULD);//false, false); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.MUST);//true, false); - q.setMinimumNumberShouldMatch(1); // 1 of 1 optional + q.setMinimumNumberShouldMatch(1); // 1 of 1 optional - verifyNrHits(q, 1); - } + verifyNrHits(q, 1); + } - public void testNoOptionalButMin() throws Exception { + public void testNoOptionalButMin() throws Exception { - /* two required, no optional */ - BooleanQuery q = new BooleanQuery(); + /* two required, no optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.add(new TermQuery(new Term("data", "2" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("data", "2")), BooleanClause.Occur.MUST);//true, false); - q.setMinimumNumberShouldMatch(1); // 1 of 0 optional + q.setMinimumNumberShouldMatch(1); // 1 of 0 optional - verifyNrHits(q, 0); - } + verifyNrHits(q, 0); + } - public void testNoOptionalButMin2() throws Exception { + public void testNoOptionalButMin2() throws Exception { - /* one required, no optional */ - BooleanQuery q = new BooleanQuery(); + /* one required, no optional */ + BooleanQuery q = new BooleanQuery(); - q.add(new TermQuery(new Term("all", "all" )), BooleanClause.Occur.MUST);//true, false); + q.add(new TermQuery(new Term("all", "all")), BooleanClause.Occur.MUST);//true, false); - q.setMinimumNumberShouldMatch(1); // 1 of 0 optional + q.setMinimumNumberShouldMatch(1); // 1 of 0 optional - verifyNrHits(q, 0); - } + verifyNrHits(q, 0); + } - public void testRandomQueries() throws Exception { - final Random rnd = newRandom(); + public void testRandomQueries() throws Exception { + final Random rnd = newRandom(); - String field="data"; + String field = "data"; - String[] vals = {"1","2","3","4","5","6","A","Z","B","Y","Z","X","foo"}; + String[] vals = {"1", "2", "3", "4", "5", "6", "A", "Z", "B", "Y", "Z", "X", "foo"}; - int maxLev=4; + int maxLev = 4; - // callback object to set a random setMinimumNumberShouldMatch - TestBoolean2.Callback minNrCB = new TestBoolean2.Callback() { - public void postCreate(BooleanQuery q) { + // callback object to set a random setMinimumNumberShouldMatch + TestBoolean2.Callback minNrCB = new TestBoolean2.Callback() { + public void postCreate(BooleanQuery q) { - BooleanClause[] c =q.getClauses(); + BooleanClause[] c = q.getClauses(); - int opt=0; + int opt = 0; - for (int i=0; i top1.totalHits) { - TestCase.fail("Constrained results not a subset:\n" + // 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(top1, 0, 0) - + CheckHits.topdocsString(top2,0,0) + + CheckHits.topdocsString(top2, 0, 0) - + "for query:" + q2.toString()); - } + + "for query:" + q2.toString()); + } - for (int hit=0; hit1.0e-6f) { + if (Math.abs(otherScore - score) > 1.0e-6f) { - TestCase.fail("Doc " + id + " scores don't match\n" + TestCase.fail("Doc " + id + " scores don't match\n" - + CheckHits.topdocsString(top1,0,0) + + CheckHits.topdocsString(top1, 0, 0) - + CheckHits.topdocsString(top2,0,0) + + CheckHits.topdocsString(top2, 0, 0) - + "for query:" + q2.toString()); - } - } - } + + "for query:" + q2.toString()); + } + } + } - // check if subset - if (!found) TestCase.fail("Doc " + id + " not found\n" + // check if subset + if (!found) TestCase.fail("Doc " + id + " not found\n" - + CheckHits.topdocsString(top1,0,0) + + CheckHits.topdocsString(top1, 0, 0) - + CheckHits.topdocsString(top2,0,0) + + CheckHits.topdocsString(top2, 0, 0) + "for query:" + q2.toString()); - } - } - // System.out.println("Total hits:"+tot); - } + } + } + // System.out.println("Total hits:"+tot); + } - - protected void printHits(String test, ScoreDoc[] h, Searcher searcher) throws Exception { + protected void printHits(String test, ScoreDoc[] h, Searcher searcher) throws Exception { - System.err.println("------- " + test + " -------"); + System.err.println("------- " + test + " -------"); - DecimalFormat f = new DecimalFormat("0.000000"); + DecimalFormat f = new DecimalFormat("0.000000"); - for (int i = 0; i < h.length; i++) { - Document d = searcher.doc(h[i].doc); - float score = h[i].score; - System.err.println("#" + i + ": " + f.format(score) + " - " + - d.get("id") + " - " + d.get("data")); - } - } + for (int i = 0; i < h.length; i++) { + Document d = searcher.doc(h[i].doc); + float score = h[i].score; + System.err.println("#" + i + ": " + f.format(score) + " - " + + d.get("id") + " - " + d.get("data")); + } + } } Index: test/org/apache/lucene/search/function/TestCustomScoreQuery.java =================================================================== --- test/org/apache/lucene/search/function/TestCustomScoreQuery.java (revision 832972) +++ test/org/apache/lucene/search/function/TestCustomScoreQuery.java Sat Nov 14 20:45:14 EST 2009 @@ -17,99 +17,113 @@ * limitations under the License. */ -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; - -import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.queryParser.QueryParser; -import org.apache.lucene.search.Explanation; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.QueryUtils; -import org.apache.lucene.search.TopDocs; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.search.*; import org.apache.lucene.util.Version; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.HashMap; + /** * Test CustomScoreQuery search. */ +@SuppressWarnings({"MagicNumber"}) public class TestCustomScoreQuery extends FunctionTestSetup { - /* @override constructor */ - public TestCustomScoreQuery(String name) { - super(name); - } - /** Test that CustomScoreQuery of Type.BYTE returns the expected scores. */ - public void testCustomScoreByte () throws CorruptIndexException, Exception { + /** + * Test that CustomScoreQuery of Type.BYTE returns the expected scores. + */ + @Test + public void testCustomScoreByte() throws IOException, ParseException { // INT field values are small enough to be parsed as byte - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.BYTE,1.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.BYTE, 1.0); - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.BYTE,2.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.BYTE, 2.0); } - /** Test that CustomScoreQuery of Type.SHORT returns the expected scores. */ - public void testCustomScoreShort () throws CorruptIndexException, Exception { + /** + * Test that CustomScoreQuery of Type.SHORT returns the expected scores. + */ + @Test + public void testCustomScoreShort() throws IOException, ParseException { // INT field values are small enough to be parsed as short - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.SHORT,1.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.SHORT, 1.0); - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.SHORT,3.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.SHORT, 3.0); } - /** Test that CustomScoreQuery of Type.INT returns the expected scores. */ - public void testCustomScoreInt () throws CorruptIndexException, Exception { + /** + * Test that CustomScoreQuery of Type.INT returns the expected scores. + */ + @Test + public void testCustomScoreInt() throws IOException, ParseException { - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.INT,1.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.INT, 1.0); - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.INT,4.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.INT, 4.0); } - /** Test that CustomScoreQuery of Type.FLOAT returns the expected scores. */ - public void testCustomScoreFloat () throws CorruptIndexException, Exception { + /** + * Test that CustomScoreQuery of Type.FLOAT returns the expected scores. + */ + @Test + public void testCustomScoreFloat() throws IOException, ParseException { // INT field can be parsed as float - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.FLOAT,1.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.FLOAT, 1.0); - doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.FLOAT,5.0); + doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.FLOAT, 5.0); // same values, but in flot format - doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,1.0); + doTestCustomScore(FLOAT_FIELD, FieldScoreQuery.Type.FLOAT, 1.0); - doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,6.0); + doTestCustomScore(FLOAT_FIELD, FieldScoreQuery.Type.FLOAT, 6.0); } // must have static class otherwise serialization tests fail + @SuppressWarnings({"SerializableHasSerializationMethods", "serial"}) private static class CustomAddQuery extends CustomScoreQuery { // constructor - CustomAddQuery (Query q, ValueSourceQuery qValSrc) { + CustomAddQuery(Query q, ValueSourceQuery qValSrc) { - super(q,qValSrc); + super(q, qValSrc); } + /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */ @Override public String name() { return "customAdd"; } + /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */ @Override public float customScore(int doc, float subQueryScore, float valSrcScore) { return subQueryScore + valSrcScore; } + /* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/ @Override public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) { - float valSrcScore = valSrcExpl==null ? 0 : valSrcExpl.getValue(); + float valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.getValue(); - Explanation exp = new Explanation( valSrcScore + subQueryExpl.getValue(), "custom score: sum of:"); + Explanation exp = new Explanation(valSrcScore + subQueryExpl.getValue(), "custom score: sum of:"); exp.addDetail(subQueryExpl); if (valSrcExpl != null) { exp.addDetail(valSrcExpl); } - return exp; - } + return exp; + } } - + // must have static class otherwise serialization tests fail + @SuppressWarnings({"SerializableHasSerializationMethods", "serial"}) private static class CustomMulAddQuery extends CustomScoreQuery { // constructor CustomMulAddQuery(Query q, ValueSourceQuery qValSrc1, ValueSourceQuery qValSrc2) { - super(q,new ValueSourceQuery[]{qValSrc1,qValSrc2}); + super(q, new ValueSourceQuery[]{qValSrc1, qValSrc2}); } + /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */ @Override public String name() { return "customMulAdd"; } + /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */ @Override public float customScore(int doc, float subQueryScore, float valSrcScores[]) { @@ -120,7 +134,8 @@ return subQueryScore + valSrcScores[0]; } return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two - } + } + /* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/ @Override public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpls[]) { @@ -137,121 +152,127 @@ Explanation exp2 = new Explanation(valSrcExpls[1].getValue() * exp.getValue(), "custom score: product of:"); exp2.addDetail(valSrcExpls[1]); exp2.addDetail(exp); - return exp2; - } + return exp2; + } } - + // Test that FieldScoreQuery returns docs with expected score. - private void doTestCustomScore (String field, FieldScoreQuery.Type tp, double dboost) throws CorruptIndexException, Exception { + private void doTestCustomScore(String field, FieldScoreQuery.Type tp, double dboost) throws IOException, ParseException { float boost = (float) dboost; IndexSearcher s = new IndexSearcher(dir, true); - FieldScoreQuery qValSrc = new FieldScoreQuery(field,tp); // a query that would score by the field + FieldScoreQuery qValSrc = new FieldScoreQuery(field, tp); // a query that would score by the field - QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, TEXT_FIELD,anlzr); + QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, TEXT_FIELD, anlzr); String qtxt = "first aid text"; // from the doc texts in FunctionQuerySetup. - + // regular (boolean) query. - Query q1 = qp.parse(qtxt); + Query q1 = qp.parse(qtxt); log(q1); - + // custom query, that should score the same as q1. - CustomScoreQuery q2CustomNeutral = new CustomScoreQuery(q1); + Query q2CustomNeutral = new CustomScoreQuery(q1); q2CustomNeutral.setBoost(boost); log(q2CustomNeutral); - + // custom query, that should (by default) multiply the scores of q1 by that of the field - CustomScoreQuery q3CustomMul = new CustomScoreQuery(q1,qValSrc); + CustomScoreQuery q3CustomMul = new CustomScoreQuery(q1, qValSrc); q3CustomMul.setStrict(true); q3CustomMul.setBoost(boost); log(q3CustomMul); - + // custom query, that should add the scores of q1 to that of the field - CustomScoreQuery q4CustomAdd = new CustomAddQuery(q1,qValSrc); + CustomScoreQuery q4CustomAdd = new CustomAddQuery(q1, qValSrc); q4CustomAdd.setStrict(true); q4CustomAdd.setBoost(boost); log(q4CustomAdd); // custom query, that multiplies and adds the field score to that of q1 - CustomScoreQuery q5CustomMulAdd = new CustomMulAddQuery(q1,qValSrc,qValSrc); + CustomScoreQuery q5CustomMulAdd = new CustomMulAddQuery(q1, qValSrc, qValSrc); q5CustomMulAdd.setStrict(true); q5CustomMulAdd.setBoost(boost); log(q5CustomMulAdd); // do al the searches - TopDocs td1 = s.search(q1,null,1000); + TopDocs td1 = s.search(q1, null, 1000); - TopDocs td2CustomNeutral = s.search(q2CustomNeutral,null,1000); + TopDocs td2CustomNeutral = s.search(q2CustomNeutral, null, 1000); - TopDocs td3CustomMul = s.search(q3CustomMul,null,1000); + TopDocs td3CustomMul = s.search(q3CustomMul, null, 1000); - TopDocs td4CustomAdd = s.search(q4CustomAdd,null,1000); + TopDocs td4CustomAdd = s.search(q4CustomAdd, null, 1000); - TopDocs td5CustomMulAdd = s.search(q5CustomMulAdd,null,1000); + TopDocs td5CustomMulAdd = s.search(q5CustomMulAdd, null, 1000); - + // put results in map so we can verify the scores although they have changed - HashMap h1 = topDocsToMap(td1); - HashMap h2CustomNeutral = topDocsToMap(td2CustomNeutral); - HashMap h3CustomMul = topDocsToMap(td3CustomMul); - HashMap h4CustomAdd = topDocsToMap(td4CustomAdd); - HashMap h5CustomMulAdd = topDocsToMap(td5CustomMulAdd); + HashMap h1 = topDocsToMap(td1); + HashMap h2CustomNeutral = topDocsToMap(td2CustomNeutral); + HashMap h3CustomMul = topDocsToMap(td3CustomMul); + HashMap h4CustomAdd = topDocsToMap(td4CustomAdd); + HashMap h5CustomMulAdd = topDocsToMap(td5CustomMulAdd); - - verifyResults(boost, s, - h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd, - q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd); + + verifyResults(boost, s, + h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd, + q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd); } - + // verify results are as expected. - private void verifyResults(float boost, IndexSearcher s, + private void verifyResults(float boost, IndexSearcher s, - HashMap h1, HashMap h2customNeutral, HashMap h3CustomMul, HashMap h4CustomAdd, HashMap h5CustomMulAdd, - Query q1, Query q2, Query q3, Query q4, Query q5) throws Exception { + HashMap h1, HashMap h2customNeutral, + HashMap h3CustomMul, HashMap h4CustomAdd, + HashMap h5CustomMulAdd, + Query q1, Query q2, Query q3, Query q4, Query q5) throws IOException { - + // verify numbers of matches - log("#hits = "+h1.size()); + log("#hits = " + h1.size()); - assertEquals("queries should have same #hits",h1.size(),h2customNeutral.size()); + assertEquals("queries should have same #hits", h1.size(), h2customNeutral.size()); - assertEquals("queries should have same #hits",h1.size(),h3CustomMul.size()); + assertEquals("queries should have same #hits", h1.size(), h3CustomMul.size()); - assertEquals("queries should have same #hits",h1.size(),h4CustomAdd.size()); + assertEquals("queries should have same #hits", h1.size(), h4CustomAdd.size()); - assertEquals("queries should have same #hits",h1.size(),h5CustomMulAdd.size()); + assertEquals("queries should have same #hits", h1.size(), h5CustomMulAdd.size()); - + + QueryUtils.check(q1, s); + QueryUtils.check(q2, s); + QueryUtils.check(q3, s); + QueryUtils.check(q4, s); + QueryUtils.check(q5, s); + // verify scores ratios - for (Iterator it = h1.keySet().iterator(); it.hasNext();) { - Integer x = (Integer) it.next(); + for (int x : h1.keySet()) { - int doc = x.intValue(); - log("doc = "+doc); + log("doc = " + x); - float fieldScore = expectedFieldScore(s.getIndexReader().document(doc).get(ID_FIELD)); + float fieldScore = expectedFieldScore(s.getIndexReader().document(x).get(ID_FIELD)); - log("fieldScore = "+fieldScore); + log("fieldScore = " + fieldScore); - assertTrue("fieldScore should not be 0",fieldScore>0); + assertTrue("fieldScore should not be 0", fieldScore > 0); - float score1 = ((Float)h1.get(x)).floatValue(); - logResult("score1=", s, q1, doc, score1); + float score1 = h1.get(x); + logResult("score1=", s, q1, x, score1); - + - float score2 = ((Float)h2customNeutral.get(x)).floatValue(); - logResult("score2=", s, q2, doc, score2); + float score2 = h2customNeutral.get(x); + logResult("score2=", s, q2, x, score2); assertEquals("same score (just boosted) for neutral", boost * score1, score2, TEST_SCORE_TOLERANCE_DELTA); - float score3 = ((Float)h3CustomMul.get(x)).floatValue(); - logResult("score3=", s, q3, doc, score3); + float score3 = h3CustomMul.get(x); + logResult("score3=", s, q3, x, score3); assertEquals("new score for custom mul", boost * fieldScore * score1, score3, TEST_SCORE_TOLERANCE_DELTA); - + - float score4 = ((Float)h4CustomAdd.get(x)).floatValue(); - logResult("score4=", s, q4, doc, score4); + float score4 = h4CustomAdd.get(x); + logResult("score4=", s, q4, x, score4); assertEquals("new score for custom add", boost * (fieldScore + score1), score4, TEST_SCORE_TOLERANCE_DELTA); - + - float score5 = ((Float)h5CustomMulAdd.get(x)).floatValue(); - logResult("score5=", s, q5, doc, score5); + float score5 = h5CustomMulAdd.get(x); + logResult("score5=", s, q5, x, score5); assertEquals("new score for custom mul add", boost * fieldScore * (score1 + fieldScore), score5, TEST_SCORE_TOLERANCE_DELTA); } } - private void logResult(String msg, IndexSearcher s, Query q, int doc, float score1) throws IOException { - QueryUtils.check(q,s); + + private void logResult(String msg, Searcher s, Query q, int doc, float score1) throws IOException { - log(msg+" "+score1); + log(msg + " " + score1); - log("Explain by: "+q); + log("Explain by: " + q); - log(s.explain(q,doc)); + log(s.explain(q, doc)); } // since custom scoring modifies the order of docs, map results // by doc ids so that we can later compare/verify them - private HashMap topDocsToMap(TopDocs td) { - HashMap h = new HashMap(); + private HashMap topDocsToMap(TopDocs td) { + HashMap h = new HashMap(); - for (int i=0; i