Peter's problem intrigued me, so I wrote my own test case using two simple Filters that filter out all but the first (or last) doc. I seem to be getting the same results he is, which is certianly. see attached test case.
while this definitely seems like a bug, it also seems like a fairly inefficinent way of approaching hte problem in general, instead of: BooleanQuery containing: a) FilteredQuery wrapping: Query for "all" -- filtered by -- RangeFilter #1 b) FilteredQuery wrapping: Query for "all" -- filtered by -- RangeFilter #2 ...it seems like it would make more sense to use... FilterQuery wrapping: Query for all -- filtered by -- ChainedFilter containing: a) RangeFilter #1 b) RangeFilter #2 : Date: Fri, 1 Apr 2005 13:29:04 -0500 : From: Erik Hatcher <[EMAIL PROTECTED]> : Reply-To: java-user@lucene.apache.org : To: java-user@lucene.apache.org : Subject: Re: FilteredQuery and Boolean AND : : Peter, : : Could you provide a straight-forward test case that indexes a few : documents into a RAMDirectory and demonstrates the problem you're : having with AND'd FilteredQuery's? : : Give me something concrete and simple and I'll dig into it further. : : Erik : : On Apr 1, 2005, at 11:13 AM, Kipping, Peter wrote: : : > Any ideas on this? I have purchased your book, Lucene in Action, which : > is quite good. To make things easier, consider the example on p212. : > In : > item 4, when you combine the queries, what happens you combine them in : > and AND fashion? The book only has OR, which works. Although it may : > work since the book only has one filtered query, but what if you made : > them both filtered queries and ANDed them? : > : > Thanks, : > Peter : > : > -----Original Message----- : > From: Kipping, Peter [mailto:[EMAIL PROTECTED] : > Sent: Friday, March 25, 2005 10:34 AM : > To: java-user@lucene.apache.org : > Subject: FilteredQuery and Boolean AND : > : > I have the following query structure: : > : > BooleanQuery q2 = new BooleanQuery(); : > TermQuery tq = new TermQuery(new Term("all_entries", "y")); : > FilteredQuery fq = new FilteredQuery(tq, ft); : > FilteredQuery fq2 = new FilteredQuery(tq, ft2); : > q2.add(fq, false, false); : > q2.add(fq2, false, false); : > : > The two filters are searches over numeric ranges. I'm using filters so : > I don't get the TooManyBooleanClauses Exception. And my TermQuery tq : > is : > just a field that has 'y' in every document so I can filter over the : > entire index. The last two lines I am creating a boolean OR, and : > everything works fine. I get back 30 documents which is correct. : > : > However when I change the last two lines to create an AND: : > : > q2.add(fq, true, false); : > q2.add(fq2, true, false); : > : > I still get back 30 documents, which is not correct. It should be 0. : > What's going on with FilteredQuery? : > : > Thanks, : > Peter : > : > : > --------------------------------------------------------------------- : > To unsubscribe, e-mail: [EMAIL PROTECTED] : > For additional commands, e-mail: [EMAIL PROTECTED] : > : > : > : > : > --------------------------------------------------------------------- : > To unsubscribe, e-mail: [EMAIL PROTECTED] : > For additional commands, e-mail: [EMAIL PROTECTED] : : : --------------------------------------------------------------------- : To unsubscribe, e-mail: [EMAIL PROTECTED] : For additional commands, e-mail: [EMAIL PROTECTED] : -Hoss
import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.search.Query; import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.analysis.SimpleAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.DateField; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Filter; import org.apache.lucene.search.FilteredQuery; import java.io.IOException; import java.util.Random; import java.util.BitSet; import junit.framework.TestCase; public class TestKippingPeterBug extends TestCase { public static final boolean F = false; public static final boolean T = true; public static String[] data = new String [] { "a b m n", "a x q r", "a b s t", "a x e f", "a" }; RAMDirectory index = new RAMDirectory(); IndexReader r; IndexSearcher s; Query ALL = new TermQuery(new Term("data","a")); public TestKippingPeterBug(String name) { super(name); } public TestKippingPeterBug() { super(); } public void setUp() throws Exception { /* build an index */ IndexWriter writer = new IndexWriter(index, new SimpleAnalyzer(), T); for (int i = 0; i < data.length; i++) { Document doc = new Document(); doc.add(Field.Keyword("id",String.valueOf(i))); doc.add(Field.Text("data",data[i])); writer.addDocument(doc); } writer.optimize(); writer.close(); r = IndexReader.open(index); s = new IndexSearcher(r); } public void testA() throws Exception { Hits result; result = s.search(ALL); assertEquals("not all docs found", data.length, result.length()); } public void testFilters() throws Exception { Filter f = new FirstFilter(); Filter l = new LastFilter(); Hits result; assertEquals("only one should be set in FirstFilter", 1, f.bits(r).cardinality()); assertEquals("only one should be set in LastFilter", 1, l.bits(r).cardinality()); result = s.search(ALL, f); assertEquals("should get one doc from FirstFilter(ALL)", 1, result.length()); assertEquals("wrong doc from FirstFilter(ALL)", 0, result.id(0)); result = s.search(ALL, l); assertEquals("should get one doc from LastFilter(ALL)", 1, result.length()); assertEquals("wrong doc from LastFilter(ALL)", data.length-1, result.id(0)); } public void testBooleanFilteredQuery() throws Exception { Filter f = new FirstFilter(); Filter l = new LastFilter(); Query ff = new FilteredQuery(ALL, f); Query ll = new FilteredQuery(ALL, l); Hits result; result = s.search(ff); assertEquals("should get one doc from FirstFilter(ALL)", 1, result.length()); assertEquals("wrong doc from FirstFilter(ALL)", 0, result.id(0)); result = s.search(ll); assertEquals("should get one doc from LastFilter(ALL)", 1, result.length()); assertEquals("wrong doc from LastFilter(ALL)", data.length-1, result.id(0)); BooleanQuery or = new BooleanQuery(); or.add(ff, false, false); or.add(ll, false, false); result = s.search(or); assertEquals("should get two docs from *or*", 2, result.length()); BooleanQuery and = new BooleanQuery(); and.add(ff, true, false); and.add(ll, true, false); result = s.search(and); assertEquals("should get no docs from *and*", 0, result.length()); } } class FirstFilter extends Filter { /** only lets the first doc in the index pass the filter */ public BitSet bits(IndexReader r) { BitSet b = new BitSet(r.maxDoc()); b.set(0); return b; } } class LastFilter extends Filter { /** only lets the last doc in the index pass the filter */ public BitSet bits(IndexReader r) { BitSet b = new BitSet(r.maxDoc()); b.set(r.maxDoc()-1); return b; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]