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 org.apache.lucene.analysis.MockAnalyzer;
21 import org.apache.lucene.document.Document;
22 import org.apache.lucene.document.Field;
23 import org.apache.lucene.index.IndexReader;
24 import org.apache.lucene.index.RandomIndexWriter;
25 import org.apache.lucene.index.Term;
26 import org.apache.lucene.search.BooleanClause.Occur;
27 import org.apache.lucene.store.Directory;
28 import org.apache.lucene.util.DocIdBitSet;
29 import org.apache.lucene.util.LuceneTestCase;
31 import java.util.BitSet;
34 * FilteredQuery JUnit tests.
36 * <p>Created: Apr 21, 2004 1:21:46 PM
41 public class TestFilteredQuery extends LuceneTestCase {
43 private IndexSearcher searcher;
44 private IndexReader reader;
45 private Directory directory;
47 private Filter filter;
50 public void setUp() throws Exception {
52 directory = newDirectory();
53 RandomIndexWriter writer = new RandomIndexWriter (random, directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
55 Document doc = new Document();
56 doc.add (newField("field", "one two three four five", Field.Store.YES, Field.Index.ANALYZED));
57 doc.add (newField("sorter", "b", Field.Store.YES, Field.Index.ANALYZED));
58 writer.addDocument (doc);
61 doc.add (newField("field", "one two three four", Field.Store.YES, Field.Index.ANALYZED));
62 doc.add (newField("sorter", "d", Field.Store.YES, Field.Index.ANALYZED));
63 writer.addDocument (doc);
66 doc.add (newField("field", "one two three y", Field.Store.YES, Field.Index.ANALYZED));
67 doc.add (newField("sorter", "a", Field.Store.YES, Field.Index.ANALYZED));
68 writer.addDocument (doc);
71 doc.add (newField("field", "one two x", Field.Store.YES, Field.Index.ANALYZED));
72 doc.add (newField("sorter", "c", Field.Store.YES, Field.Index.ANALYZED));
73 writer.addDocument (doc);
75 // tests here require single segment (eg try seed
76 // 8239472272678419952L), because SingleDocTestFilter(x)
77 // blindly accepts that docID in any sub-segment
80 reader = writer.getReader();
83 searcher = newSearcher(reader);
84 query = new TermQuery (new Term ("field", "three"));
85 filter = newStaticFilterB();
88 // must be static for serialization tests
89 private static Filter newStaticFilterB() {
92 public DocIdSet getDocIdSet (IndexReader reader) {
93 BitSet bitset = new BitSet(5);
96 return new DocIdBitSet(bitset);
102 public void tearDown() throws Exception {
109 public void testFilteredQuery()
111 Query filteredquery = new FilteredQuery (query, filter);
112 ScoreDoc[] hits = searcher.search (filteredquery, null, 1000).scoreDocs;
113 assertEquals (1, hits.length);
114 assertEquals (1, hits[0].doc);
115 QueryUtils.check(random, filteredquery,searcher);
117 hits = searcher.search (filteredquery, null, 1000, new Sort(new SortField("sorter", SortField.STRING))).scoreDocs;
118 assertEquals (1, hits.length);
119 assertEquals (1, hits[0].doc);
121 filteredquery = new FilteredQuery (new TermQuery (new Term ("field", "one")), filter);
122 hits = searcher.search (filteredquery, null, 1000).scoreDocs;
123 assertEquals (2, hits.length);
124 QueryUtils.check(random, filteredquery,searcher);
126 filteredquery = new FilteredQuery (new TermQuery (new Term ("field", "x")), filter);
127 hits = searcher.search (filteredquery, null, 1000).scoreDocs;
128 assertEquals (1, hits.length);
129 assertEquals (3, hits[0].doc);
130 QueryUtils.check(random, filteredquery,searcher);
132 filteredquery = new FilteredQuery (new TermQuery (new Term ("field", "y")), filter);
133 hits = searcher.search (filteredquery, null, 1000).scoreDocs;
134 assertEquals (0, hits.length);
135 QueryUtils.check(random, filteredquery,searcher);
138 Filter f = newStaticFilterA();
141 BooleanQuery bq1 = new BooleanQuery();
142 TermQuery tq = new TermQuery (new Term ("field", "one"));
144 bq1.add(tq, Occur.MUST);
145 bq1.add(new TermQuery (new Term ("field", "five")), Occur.MUST);
147 BooleanQuery bq2 = new BooleanQuery();
148 tq = new TermQuery (new Term ("field", "one"));
149 filteredquery = new FilteredQuery(tq, f);
150 filteredquery.setBoost(boost);
151 bq2.add(filteredquery, Occur.MUST);
152 bq2.add(new TermQuery (new Term ("field", "five")), Occur.MUST);
153 assertScoreEquals(bq1, bq2);
155 assertEquals(boost, filteredquery.getBoost(), 0);
156 assertEquals(1.0f, tq.getBoost(), 0); // the boost value of the underlying query shouldn't have changed
159 // must be static for serialization tests
160 private static Filter newStaticFilterA() {
161 return new Filter() {
163 public DocIdSet getDocIdSet (IndexReader reader) {
164 BitSet bitset = new BitSet(5);
166 return new DocIdBitSet(bitset);
172 * Tests whether the scores of the two queries are the same.
174 public void assertScoreEquals(Query q1, Query q2) throws Exception {
175 ScoreDoc[] hits1 = searcher.search (q1, null, 1000).scoreDocs;
176 ScoreDoc[] hits2 = searcher.search (q2, null, 1000).scoreDocs;
178 assertEquals(hits1.length, hits2.length);
180 for (int i = 0; i < hits1.length; i++) {
181 assertEquals(hits1[i].score, hits2[i].score, 0.0000001f);
186 * This tests FilteredQuery's rewrite correctness
188 public void testRangeQuery() throws Exception {
189 TermRangeQuery rq = new TermRangeQuery(
190 "sorter", "b", "d", true, true);
192 Query filteredquery = new FilteredQuery(rq, filter);
193 ScoreDoc[] hits = searcher.search(filteredquery, null, 1000).scoreDocs;
194 assertEquals(2, hits.length);
195 QueryUtils.check(random, filteredquery,searcher);
198 public void testBoolean() throws Exception {
199 BooleanQuery bq = new BooleanQuery();
200 Query query = new FilteredQuery(new MatchAllDocsQuery(),
201 new SingleDocTestFilter(0));
202 bq.add(query, BooleanClause.Occur.MUST);
203 query = new FilteredQuery(new MatchAllDocsQuery(),
204 new SingleDocTestFilter(1));
205 bq.add(query, BooleanClause.Occur.MUST);
206 ScoreDoc[] hits = searcher.search(bq, null, 1000).scoreDocs;
207 assertEquals(0, hits.length);
208 QueryUtils.check(random, query,searcher);
211 // Make sure BooleanQuery, which does out-of-order
212 // scoring, inside FilteredQuery, works
213 public void testBoolean2() throws Exception {
214 BooleanQuery bq = new BooleanQuery();
215 Query query = new FilteredQuery(bq,
216 new SingleDocTestFilter(0));
217 bq.add(new TermQuery(new Term("field", "one")), BooleanClause.Occur.SHOULD);
218 bq.add(new TermQuery(new Term("field", "two")), BooleanClause.Occur.SHOULD);
219 ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
220 assertEquals(1, hits.length);
221 QueryUtils.check(random, query,searcher);