1
package org.apache.lucene.search;
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
11
* http://www.apache.org/licenses/LICENSE-2.0
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.
20
import java.util.Calendar;
21
import java.util.GregorianCalendar;
23
import org.apache.lucene.document.Document;
24
import org.apache.lucene.document.Field;
25
import org.apache.lucene.index.IndexReader;
26
import org.apache.lucene.index.RandomIndexWriter;
27
import org.apache.lucene.index.Term;
28
import org.apache.lucene.search.BooleanClause;
29
import org.apache.lucene.search.BooleanQuery;
30
import org.apache.lucene.search.CachingWrapperFilter;
31
import org.apache.lucene.search.Filter;
32
import org.apache.lucene.search.IndexSearcher;
33
import org.apache.lucene.search.MatchAllDocsQuery;
34
import org.apache.lucene.search.Query;
35
import org.apache.lucene.search.QueryWrapperFilter;
36
import org.apache.lucene.search.Searcher;
37
import org.apache.lucene.search.TermQuery;
38
import org.apache.lucene.search.TermRangeFilter;
39
import org.apache.lucene.search.TopDocs;
40
import org.apache.lucene.store.Directory;
41
import org.apache.lucene.util.LuceneTestCase;
43
public class ChainedFilterTest extends LuceneTestCase {
44
public static final int MAX = 500;
46
private Directory directory;
47
private IndexSearcher searcher;
48
private IndexReader reader;
50
// private DateFilter dateFilter; DateFilter was deprecated and removed
51
private TermRangeFilter dateFilter;
52
private QueryWrapperFilter bobFilter;
53
private QueryWrapperFilter sueFilter;
56
public void setUp() throws Exception {
58
directory = newDirectory();
59
RandomIndexWriter writer = new RandomIndexWriter(random, directory);
60
Calendar cal = new GregorianCalendar();
62
cal.setTimeInMillis(1041397200000L); // 2003 January 01
64
for (int i = 0; i < MAX; i++) {
65
Document doc = new Document();
66
doc.add(newField("key", "" + (i + 1), Field.Store.YES, Field.Index.NOT_ANALYZED));
67
doc.add(newField("owner", (i < MAX / 2) ? "bob" : "sue", Field.Store.YES, Field.Index.NOT_ANALYZED));
68
doc.add(newField("date", cal.getTime().toString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
69
writer.addDocument(doc);
71
cal.add(Calendar.DATE, 1);
73
reader = writer.getReader();
76
searcher = newSearcher(reader);
78
// query for everything to make life easier
79
BooleanQuery bq = new BooleanQuery();
80
bq.add(new TermQuery(new Term("owner", "bob")), BooleanClause.Occur.SHOULD);
81
bq.add(new TermQuery(new Term("owner", "sue")), BooleanClause.Occur.SHOULD);
84
// date filter matches everything too
85
//Date pastTheEnd = parseDate("2099 Jan 1");
86
// dateFilter = DateFilter.Before("date", pastTheEnd);
87
// just treat dates as strings and select the whole range for now...
88
dateFilter = new TermRangeFilter("date","","ZZZZ",true,true);
90
bobFilter = new QueryWrapperFilter(
91
new TermQuery(new Term("owner", "bob")));
92
sueFilter = new QueryWrapperFilter(
93
new TermQuery(new Term("owner", "sue")));
97
public void tearDown() throws Exception {
104
private ChainedFilter getChainedFilter(Filter[] chain, int[] logic) {
106
return new ChainedFilter(chain);
108
return new ChainedFilter(chain, logic);
112
private ChainedFilter getChainedFilter(Filter[] chain, int logic) {
113
return new ChainedFilter(chain, logic);
117
public void testSingleFilter() throws Exception {
118
ChainedFilter chain = getChainedFilter(new Filter[] {dateFilter}, null);
120
int numHits = searcher.search(query, chain, 1000).totalHits;
121
assertEquals(MAX, numHits);
123
chain = new ChainedFilter(new Filter[] {bobFilter});
124
numHits = searcher.search(query, chain, 1000).totalHits;
125
assertEquals(MAX / 2, numHits);
127
chain = getChainedFilter(new Filter[] {bobFilter}, new int[] {ChainedFilter.AND});
128
TopDocs hits = searcher.search(query, chain, 1000);
129
numHits = hits.totalHits;
130
assertEquals(MAX / 2, numHits);
131
assertEquals("bob", searcher.doc(hits.scoreDocs[0].doc).get("owner"));
133
chain = getChainedFilter(new Filter[] {bobFilter}, new int[] {ChainedFilter.ANDNOT});
134
hits = searcher.search(query, chain, 1000);
135
numHits = hits.totalHits;
136
assertEquals(MAX / 2, numHits);
137
assertEquals("sue", searcher.doc(hits.scoreDocs[0].doc).get("owner"));
140
public void testOR() throws Exception {
141
ChainedFilter chain = getChainedFilter(
142
new Filter[] {sueFilter, bobFilter}, null);
144
int numHits = searcher.search(query, chain, 1000).totalHits;
145
assertEquals("OR matches all", MAX, numHits);
148
public void testAND() throws Exception {
149
ChainedFilter chain = getChainedFilter(
150
new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND);
152
TopDocs hits = searcher.search(query, chain, 1000);
153
assertEquals("AND matches just bob", MAX / 2, hits.totalHits);
154
assertEquals("bob", searcher.doc(hits.scoreDocs[0].doc).get("owner"));
157
public void testXOR() throws Exception {
158
ChainedFilter chain = getChainedFilter(
159
new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR);
161
TopDocs hits = searcher.search(query, chain, 1000);
162
assertEquals("XOR matches sue", MAX / 2, hits.totalHits);
163
assertEquals("sue", searcher.doc(hits.scoreDocs[0].doc).get("owner"));
166
public void testANDNOT() throws Exception {
167
ChainedFilter chain = getChainedFilter(
168
new Filter[]{dateFilter, sueFilter},
169
new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT});
171
TopDocs hits = searcher.search(query, chain, 1000);
172
assertEquals("ANDNOT matches just bob",
173
MAX / 2, hits.totalHits);
174
assertEquals("bob", searcher.doc(hits.scoreDocs[0].doc).get("owner"));
176
chain = getChainedFilter(
177
new Filter[]{bobFilter, bobFilter},
178
new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT});
180
hits = searcher.search(query, chain, 1000);
181
assertEquals("ANDNOT bob ANDNOT bob matches all sues",
182
MAX / 2, hits.totalHits);
183
assertEquals("sue", searcher.doc(hits.scoreDocs[0].doc).get("owner"));
187
private Date parseDate(String s) throws ParseException {
188
return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s);
192
public void testWithCachingFilter() throws Exception {
193
Directory dir = newDirectory();
194
RandomIndexWriter writer = new RandomIndexWriter(random, dir);
195
IndexReader reader = writer.getReader();
198
IndexSearcher searcher = newSearcher(reader);
200
Query query = new TermQuery(new Term("none", "none"));
202
QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
203
CachingWrapperFilter cachingFilter = new CachingWrapperFilter(queryFilter);
205
searcher.search(query, cachingFilter, 1);
207
CachingWrapperFilter cachingFilter2 = new CachingWrapperFilter(queryFilter);
208
Filter[] chain = new Filter[2];
209
chain[0] = cachingFilter;
210
chain[1] = cachingFilter2;
211
ChainedFilter cf = new ChainedFilter(chain);
213
// throws java.lang.ClassCastException: org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
214
searcher.search(new MatchAllDocsQuery(), cf, 1);