pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / backwards / src / test / org / apache / lucene / search / TestFilteredSearch.java
1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.apache.lucene.search;
19
20 import java.io.IOException;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import org.apache.lucene.analysis.MockAnalyzer;
25 import org.apache.lucene.document.Document;
26 import org.apache.lucene.document.Field;
27 import org.apache.lucene.index.CorruptIndexException;
28 import org.apache.lucene.index.IndexReader;
29 import org.apache.lucene.index.IndexWriter;
30 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
31 import org.apache.lucene.index.Term;
32 import org.apache.lucene.store.Directory;
33 import org.apache.lucene.store.LockObtainFailedException;
34 import org.apache.lucene.util.LuceneTestCase;
35 import org.apache.lucene.util.FixedBitSet;
36
37
38 /**
39  *
40  */
41 public class TestFilteredSearch extends LuceneTestCase {
42
43   private static final String FIELD = "category";
44   
45   public void testFilteredSearch() throws CorruptIndexException, LockObtainFailedException, IOException {
46     boolean enforceSingleSegment = true;
47     Directory directory = newDirectory();
48     int[] filterBits = {1, 36};
49     SimpleDocIdSetFilter filter = new SimpleDocIdSetFilter(filterBits);
50     IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
51     searchFiltered(writer, directory, filter, enforceSingleSegment);
52     // run the test on more than one segment
53     enforceSingleSegment = false;
54     // reset - it is stateful
55     filter.reset();
56     writer.close();
57     writer = new IndexWriter(directory, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE).setMaxBufferedDocs(10).setMergePolicy(newLogMergePolicy()));
58     // we index 60 docs - this will create 6 segments
59     searchFiltered(writer, directory, filter, enforceSingleSegment);
60     writer.close();
61     directory.close();
62   }
63
64   public void searchFiltered(IndexWriter writer, Directory directory, SimpleDocIdSetFilter filter, boolean optimize) {
65     try {
66       for (int i = 0; i < 60; i++) {//Simple docs
67         Document doc = new Document();
68         doc.add(newField(FIELD, Integer.toString(i), Field.Store.YES, Field.Index.NOT_ANALYZED));
69         writer.addDocument(doc);
70       }
71       if(optimize)
72         writer.optimize();
73       writer.close();
74
75       BooleanQuery booleanQuery = new BooleanQuery();
76       booleanQuery.add(new TermQuery(new Term(FIELD, "36")), BooleanClause.Occur.SHOULD);
77      
78      
79       IndexSearcher indexSearcher = new IndexSearcher(directory, true);
80       filter.setDocBases(indexSearcher.getIndexReader());
81       ScoreDoc[] hits = indexSearcher.search(booleanQuery, filter, 1000).scoreDocs;
82       assertEquals("Number of matched documents", 1, hits.length);
83       indexSearcher.close();
84     }
85     catch (IOException e) {
86       fail(e.getMessage());
87     }
88     
89   }
90  
91   public static final class SimpleDocIdSetFilter extends Filter {
92     private final int[] docs;
93     private int index;
94     private Map<IndexReader,Integer> docBasePerSub;
95
96     public SimpleDocIdSetFilter(int[] docs) {
97       this.docs = docs;
98     }
99
100     public void setDocBases(IndexReader r) {
101       int maxDoc = 0;
102       docBasePerSub = new HashMap<IndexReader,Integer>();
103       for(IndexReader sub : r.getSequentialSubReaders()) {
104         docBasePerSub.put(sub, maxDoc);
105         maxDoc += sub.maxDoc();
106       }
107     }
108
109     @Override
110     public DocIdSet getDocIdSet(IndexReader reader) {
111       final FixedBitSet set = new FixedBitSet(reader.maxDoc());
112       final int docBase = docBasePerSub.get(reader);
113       final int limit = docBase+reader.maxDoc();
114       for (;index < docs.length; index++) {
115         final int docId = docs[index];
116         if (docId > limit)
117           break;
118         if (docId >= docBase) {
119           set.set(docId-docBase);
120         }
121       }
122       return set.cardinality() == 0 ? null:set;
123     }
124     
125     public void reset(){
126       index = 0;
127     }
128   }
129
130 }