pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / queries / src / test / org / apache / lucene / search / BooleanFilterTest.java
1 package org.apache.lucene.search;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22 import org.apache.lucene.analysis.MockAnalyzer;
23 import org.apache.lucene.analysis.MockTokenizer;
24 import org.apache.lucene.document.Document;
25 import org.apache.lucene.document.Field;
26 import org.apache.lucene.index.IndexReader;
27 import org.apache.lucene.index.RandomIndexWriter;
28 import org.apache.lucene.index.Term;
29 import org.apache.lucene.search.BooleanClause.Occur;
30 import org.apache.lucene.store.Directory;
31 import org.apache.lucene.util.LuceneTestCase;
32
33 public class BooleanFilterTest extends LuceneTestCase {
34   private Directory directory;
35   private IndexReader reader;
36
37   @Override
38   public void setUp() throws Exception {
39     super.setUp();
40     directory = newDirectory();
41     RandomIndexWriter writer = new RandomIndexWriter(random, directory, new MockAnalyzer(random, MockTokenizer.WHITESPACE, false));
42     
43     //Add series of docs with filterable fields : acces rights, prices, dates and "in-stock" flags
44     addDoc(writer, "admin guest", "010", "20040101","Y");
45     addDoc(writer, "guest", "020", "20040101","Y");
46     addDoc(writer, "guest", "020", "20050101","Y");
47     addDoc(writer, "admin", "020", "20050101","Maybe");
48     addDoc(writer, "admin guest", "030", "20050101","N");
49     reader = writer.getReader();
50     writer.close();     
51   }
52
53   @Override
54   public void tearDown() throws Exception {
55     reader.close();
56     directory.close();
57     super.tearDown();
58   }
59
60   private void addDoc(RandomIndexWriter writer, String accessRights, String price, String date, String inStock) throws IOException
61   {
62     Document doc=new Document();
63     doc.add(newField("accessRights",accessRights,Field.Store.YES,Field.Index.ANALYZED));
64     doc.add(newField("price",price,Field.Store.YES,Field.Index.ANALYZED));
65     doc.add(newField("date",date,Field.Store.YES,Field.Index.ANALYZED));
66     doc.add(newField("inStock",inStock,Field.Store.YES,Field.Index.ANALYZED));
67     writer.addDocument(doc);
68   }
69
70   private Filter getRangeFilter(String field,String lowerPrice, String upperPrice)
71   {
72     Filter f = new TermRangeFilter(field,lowerPrice,upperPrice,true,true);
73     return f;
74   }
75
76   private Filter getTermsFilter(String field, String text) {
77     TermsFilter tf = new TermsFilter();
78     tf.addTerm(new Term(field, text));
79
80     return tf;
81   }
82
83   private Filter getWrappedTermQuery(String field, String text) {
84     return new QueryWrapperFilter(new TermQuery(new Term(field, text)));
85   }
86
87   private Filter getNullDISFilter() {
88     return new Filter() {
89       @Override
90       public DocIdSet getDocIdSet(IndexReader context) {
91         return null;
92       }
93     };
94   }
95
96   private Filter getNullDISIFilter() {
97     return new Filter() {
98       @Override
99       public DocIdSet getDocIdSet(IndexReader context) {
100         return new DocIdSet() {
101           @Override
102           public DocIdSetIterator iterator() {
103             return null;
104           }
105           
106           @Override
107           public boolean isCacheable() {
108             return true;
109           }
110         };
111       }
112     };
113   }
114
115   private void tstFilterCard(String mes, int expected, Filter filt)
116       throws Exception {
117     // BooleanFilter never returns null DIS or null DISI!
118     DocIdSetIterator disi = filt.getDocIdSet(reader).iterator();
119     int actual = 0;
120     while (disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
121       actual++;
122     }
123     assertEquals(mes, expected, actual);
124   }
125
126
127   public void testShould() throws Exception {
128     BooleanFilter booleanFilter = new BooleanFilter();
129     booleanFilter.add(getTermsFilter("price", "030"), Occur.SHOULD);
130     tstFilterCard("Should retrieves only 1 doc", 1, booleanFilter);
131     
132     // same with a real DISI (no OpenBitSetIterator)
133     booleanFilter = new BooleanFilter();
134     booleanFilter.add(getWrappedTermQuery("price", "030"), Occur.SHOULD);
135     tstFilterCard("Should retrieves only 1 doc", 1, booleanFilter);
136   }
137
138   public void testShoulds() throws Exception {
139     BooleanFilter booleanFilter = new BooleanFilter();
140     booleanFilter.add(getRangeFilter("price", "010", "020"), Occur.SHOULD);
141     booleanFilter.add(getRangeFilter("price", "020", "030"), Occur.SHOULD);
142     tstFilterCard("Shoulds are Ored together", 5, booleanFilter);
143   }
144
145   public void testShouldsAndMustNot() throws Exception {
146     BooleanFilter booleanFilter = new BooleanFilter();
147     booleanFilter.add(getRangeFilter("price", "010", "020"), Occur.SHOULD);
148     booleanFilter.add(getRangeFilter("price", "020", "030"), Occur.SHOULD);
149     booleanFilter.add(getTermsFilter("inStock", "N"), Occur.MUST_NOT);
150     tstFilterCard("Shoulds Ored but AndNot", 4, booleanFilter);
151
152     booleanFilter.add(getTermsFilter("inStock", "Maybe"), Occur.MUST_NOT);
153     tstFilterCard("Shoulds Ored but AndNots", 3, booleanFilter);
154     
155     // same with a real DISI (no OpenBitSetIterator)
156     booleanFilter = new BooleanFilter();
157     booleanFilter.add(getRangeFilter("price", "010", "020"), Occur.SHOULD);
158     booleanFilter.add(getRangeFilter("price", "020", "030"), Occur.SHOULD);
159     booleanFilter.add(getWrappedTermQuery("inStock", "N"), Occur.MUST_NOT);
160     tstFilterCard("Shoulds Ored but AndNot", 4, booleanFilter);
161
162     booleanFilter.add(getWrappedTermQuery("inStock", "Maybe"), Occur.MUST_NOT);
163     tstFilterCard("Shoulds Ored but AndNots", 3, booleanFilter);
164   }
165
166   public void testShouldsAndMust() throws Exception {
167     BooleanFilter booleanFilter = new BooleanFilter();
168     booleanFilter.add(getRangeFilter("price", "010", "020"), Occur.SHOULD);
169     booleanFilter.add(getRangeFilter("price", "020", "030"), Occur.SHOULD);
170     booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
171     tstFilterCard("Shoulds Ored but MUST", 3, booleanFilter);
172     
173     // same with a real DISI (no OpenBitSetIterator)
174     booleanFilter = new BooleanFilter();
175     booleanFilter.add(getRangeFilter("price", "010", "020"), Occur.SHOULD);
176     booleanFilter.add(getRangeFilter("price", "020", "030"), Occur.SHOULD);
177     booleanFilter.add(getWrappedTermQuery("accessRights", "admin"), Occur.MUST);
178     tstFilterCard("Shoulds Ored but MUST", 3, booleanFilter);
179   }
180
181   public void testShouldsAndMusts() throws Exception {
182     BooleanFilter booleanFilter = new BooleanFilter();
183     booleanFilter.add(getRangeFilter("price", "010", "020"), Occur.SHOULD);
184     booleanFilter.add(getRangeFilter("price", "020", "030"), Occur.SHOULD);
185     booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
186     booleanFilter.add(getRangeFilter("date", "20040101", "20041231"), Occur.MUST);
187     tstFilterCard("Shoulds Ored but MUSTs ANDED", 1, booleanFilter);
188   }
189
190   public void testShouldsAndMustsAndMustNot() throws Exception {
191     BooleanFilter booleanFilter = new BooleanFilter();
192     booleanFilter.add(getRangeFilter("price", "030", "040"), Occur.SHOULD);
193     booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
194     booleanFilter.add(getRangeFilter("date", "20050101", "20051231"), Occur.MUST);
195     booleanFilter.add(getTermsFilter("inStock", "N"), Occur.MUST_NOT);
196     tstFilterCard("Shoulds Ored but MUSTs ANDED and MustNot", 0, booleanFilter);
197     
198     // same with a real DISI (no OpenBitSetIterator)
199     booleanFilter = new BooleanFilter();
200     booleanFilter.add(getRangeFilter("price", "030", "040"), Occur.SHOULD);
201     booleanFilter.add(getWrappedTermQuery("accessRights", "admin"), Occur.MUST);
202     booleanFilter.add(getRangeFilter("date", "20050101", "20051231"), Occur.MUST);
203     booleanFilter.add(getWrappedTermQuery("inStock", "N"), Occur.MUST_NOT);
204     tstFilterCard("Shoulds Ored but MUSTs ANDED and MustNot", 0, booleanFilter);
205   }
206
207   public void testJustMust() throws Exception {
208     BooleanFilter booleanFilter = new BooleanFilter();
209     booleanFilter.add(getTermsFilter("accessRights", "admin"), Occur.MUST);
210     tstFilterCard("MUST", 3, booleanFilter);
211     
212     // same with a real DISI (no OpenBitSetIterator)
213     booleanFilter = new BooleanFilter();
214     booleanFilter.add(getWrappedTermQuery("accessRights", "admin"), Occur.MUST);
215     tstFilterCard("MUST", 3, booleanFilter);
216   }
217
218   public void testJustMustNot() throws Exception {
219     BooleanFilter booleanFilter = new BooleanFilter();
220     booleanFilter.add(getTermsFilter("inStock", "N"), Occur.MUST_NOT);
221     tstFilterCard("MUST_NOT", 4, booleanFilter);
222     
223     // same with a real DISI (no OpenBitSetIterator)
224     booleanFilter = new BooleanFilter();
225     booleanFilter.add(getWrappedTermQuery("inStock", "N"), Occur.MUST_NOT);
226     tstFilterCard("MUST_NOT", 4, booleanFilter);
227   }
228
229   public void testMustAndMustNot() throws Exception {
230     BooleanFilter booleanFilter = new BooleanFilter();
231     booleanFilter.add(getTermsFilter("inStock", "N"), Occur.MUST);
232     booleanFilter.add(getTermsFilter("price", "030"), Occur.MUST_NOT);
233     tstFilterCard("MUST_NOT wins over MUST for same docs", 0, booleanFilter);
234     
235     // same with a real DISI (no OpenBitSetIterator)
236     booleanFilter = new BooleanFilter();
237     booleanFilter.add(getWrappedTermQuery("inStock", "N"), Occur.MUST);
238     booleanFilter.add(getWrappedTermQuery("price", "030"), Occur.MUST_NOT);
239     tstFilterCard("MUST_NOT wins over MUST for same docs", 0, booleanFilter);
240   }
241
242   public void testEmpty() throws Exception {
243     BooleanFilter booleanFilter = new BooleanFilter();
244     tstFilterCard("empty BooleanFilter returns no results", 0, booleanFilter);
245   }
246
247   public void testCombinedNullDocIdSets() throws Exception {
248     BooleanFilter booleanFilter = new BooleanFilter();
249     booleanFilter.add(getTermsFilter("price", "030"), Occur.MUST);
250     booleanFilter.add(getNullDISFilter(), Occur.MUST);
251     tstFilterCard("A MUST filter that returns a null DIS should never return documents", 0, booleanFilter);
252     
253     booleanFilter = new BooleanFilter();
254     booleanFilter.add(getTermsFilter("price", "030"), Occur.MUST);
255     booleanFilter.add(getNullDISIFilter(), Occur.MUST);
256     tstFilterCard("A MUST filter that returns a null DISI should never return documents", 0, booleanFilter);
257     
258     booleanFilter = new BooleanFilter();
259     booleanFilter.add(getTermsFilter("price", "030"), Occur.SHOULD);
260     booleanFilter.add(getNullDISFilter(), Occur.SHOULD);
261     tstFilterCard("A SHOULD filter that returns a null DIS should be invisible", 1, booleanFilter);
262     
263     booleanFilter = new BooleanFilter();
264     booleanFilter.add(getTermsFilter("price", "030"), Occur.SHOULD);
265     booleanFilter.add(getNullDISIFilter(), Occur.SHOULD);
266     tstFilterCard("A SHOULD filter that returns a null DISI should be invisible", 1, booleanFilter);
267     
268     booleanFilter = new BooleanFilter();
269     booleanFilter.add(getTermsFilter("price", "030"), Occur.MUST);
270     booleanFilter.add(getNullDISFilter(), Occur.MUST_NOT);
271     tstFilterCard("A MUST_NOT filter that returns a null DIS should be invisible", 1, booleanFilter);
272     
273     booleanFilter = new BooleanFilter();
274     booleanFilter.add(getTermsFilter("price", "030"), Occur.MUST);
275     booleanFilter.add(getNullDISIFilter(), Occur.MUST_NOT);
276     tstFilterCard("A MUST_NOT filter that returns a null DISI should be invisible", 1, booleanFilter);
277   }
278
279   public void testJustNullDocIdSets() throws Exception {
280     BooleanFilter booleanFilter = new BooleanFilter();
281     booleanFilter.add(getNullDISFilter(), Occur.MUST);
282     tstFilterCard("A MUST filter that returns a null DIS should never return documents", 0, booleanFilter);
283     
284     booleanFilter = new BooleanFilter();
285     booleanFilter.add(getNullDISIFilter(), Occur.MUST);
286     tstFilterCard("A MUST filter that returns a null DISI should never return documents", 0, booleanFilter);
287     
288     booleanFilter = new BooleanFilter();
289     booleanFilter.add(getNullDISFilter(), Occur.SHOULD);
290     tstFilterCard("A single SHOULD filter that returns a null DIS should never return documents", 0, booleanFilter);
291     
292     booleanFilter = new BooleanFilter();
293     booleanFilter.add(getNullDISIFilter(), Occur.SHOULD);
294     tstFilterCard("A single SHOULD filter that returns a null DISI should never return documents", 0, booleanFilter);
295     
296     booleanFilter = new BooleanFilter();
297     booleanFilter.add(getNullDISFilter(), Occur.MUST_NOT);
298     tstFilterCard("A single MUST_NOT filter that returns a null DIS should be invisible", 5, booleanFilter);
299     
300     booleanFilter = new BooleanFilter();
301     booleanFilter.add(getNullDISIFilter(), Occur.MUST_NOT);
302     tstFilterCard("A single MUST_NOT filter that returns a null DIS should be invisible", 5, booleanFilter);
303   }
304 }