IndexSearcher.java
001 package gate.creole.annic.apache.lucene.search;
002 
003 /**
004  * Copyright 2004 The Apache Software Foundation
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 
019 import java.io.IOException;
020 import java.util.*;
021 
022 import gate.creole.annic.apache.lucene.store.Directory;
023 import gate.creole.annic.apache.lucene.document.Document;
024 import gate.creole.annic.apache.lucene.index.IndexReader;
025 import gate.creole.annic.apache.lucene.index.Term;
026 
027 /**
028  * Implements search over a single IndexReader.
029  
030  <p>
031  * Applications usually need only call the inherited {@link #search(Query)} or
032  {@link #search(Query,Filter)} methods.
033  */
034 @SuppressWarnings({"rawtypes","unchecked"})
035 public class IndexSearcher extends Searcher {
036   IndexReader reader;
037 
038   private boolean closeReader;
039   
040   /** Creates a searcher searching the index in the named directory. */
041   public IndexSearcher(String paththrows IOException {
042     this(IndexReader.open(path)true);
043   }
044 
045   /** Creates a searcher searching the index in the provided directory. */
046   public IndexSearcher(Directory directorythrows IOException {
047     this(IndexReader.open(directory)true);
048   }
049 
050   /** Creates a searcher searching the provided index. */
051   public IndexSearcher(IndexReader r) {
052     this(r, false);
053   }
054 
055   private IndexSearcher(IndexReader r, boolean closeReader) {
056     reader = r;
057     this.closeReader = closeReader;
058   }
059 
060   /**
061    * Note that the underlying IndexReader is not closed, if IndexSearcher was
062    * constructed with IndexSearcher(IndexReader r). If the IndexReader was
063    * supplied implicitly by specifying a directory, then the IndexReader gets
064    * closed.
065    */
066   @Override
067   public void close() throws IOException {
068     if (closeReader)
069       reader.close();
070   }
071 
072   // inherit javadoc
073   @Override
074   public int docFreq(Term termthrows IOException {
075     return reader.docFreq(term);
076   }
077 
078   // inherit javadoc
079   @Override
080   public Document doc(int ithrows IOException {
081     return reader.document(i);
082   }
083 
084   // inherit javadoc
085   @Override
086   public int maxDoc() throws IOException {
087     return reader.maxDoc();
088   }
089 
090   // inherit javadoc
091   @Override
092   public TopDocs search(Query query, Filter filter, final int nDocs)
093       throws IOException {
094     initializeTermPositions();
095     Scorer scorer = query.weight(this)
096         .scorer(reader,/* Niraj */this /* End */);
097     if (scorer == null)
098       return new TopDocs(0new ScoreDoc[0]);
099     final BitSet bits = filter != null ? filter.bits(readernull;
100     final HitQueue hq = new HitQueue(nDocs);
101     final int[] totalHits = new int[1];
102     scorer.score(new HitCollector() {
103       @Override
104       public final void collect(int doc, float score) {
105         if (score > 0.0f && // ignore zeroed buckets
106             (bits == null || bits.get(doc))) { // skip docs not in
107                               // bits
108           totalHits[0]++;
109           hq.insert(new ScoreDoc(doc, score));
110         }
111       }
112     },/* Niraj */this /* End */);
113 
114     ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
115     for (int i = hq.size() 1; i >= 0; i--)
116       // put docs in array
117       scoreDocs[i(ScoreDochq.pop();
118 
119     return new TopDocs(totalHits[0], scoreDocs);
120   }
121 
122   // inherit javadoc
123   @Override
124   public TopFieldDocs search(Query query, Filter filter, final int nDocs,
125       Sort sortthrows IOException {
126     initializeTermPositions();
127     Scorer scorer = query.weight(this).scorer(reader, this);
128     if (scorer == null)
129       return new TopFieldDocs(0new ScoreDoc[0], sort.fields);
130 
131     final BitSet bits = filter != null ? filter.bits(readernull;
132     final FieldSortedHitQueue hq = new FieldSortedHitQueue(reader,
133         sort.fields, nDocs);
134     final int[] totalHits = new int[1];
135     scorer.score(new HitCollector() {
136       @Override
137       public final void collect(int doc, float score) {
138         if (score > 0.0f && // ignore zeroed buckets
139             (bits == null || bits.get(doc))) { // skip docs not in
140                               // bits
141           totalHits[0]++;
142           hq.insert(new FieldDoc(doc, score));
143         }
144       }
145     }this);
146 
147     ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
148     for (int i = hq.size() 1; i >= 0; i--)
149       // put docs in array
150       scoreDocs[i= hq.fillFields((FieldDochq.pop());
151 
152     return new TopFieldDocs(totalHits[0], scoreDocs, hq.getFields());
153   }
154 
155   // inherit javadoc
156   @Override
157   public void search(Query query, Filter filter, final HitCollector results)
158       throws IOException {
159     initializeTermPositions();
160     HitCollector collector = results;
161     if (filter != null) {
162       final BitSet bits = filter.bits(reader);
163       collector = new HitCollector() {
164         @Override
165         public final void collect(int doc, float score) {
166           if (bits.get(doc)) { // skip docs not in bits
167             results.collect(doc, score);
168           }
169         }
170       };
171     }
172 
173     Scorer scorer = query.weight(this).scorer(reader, this);
174     if (scorer == null)
175       return;
176     scorer.score(collector, this);
177   }
178 
179   @Override
180   public Query rewrite(Query originalthrows IOException {
181     Query query = original;
182     for (Query rewrittenQuery = query.rewrite(reader); rewrittenQuery != query; rewrittenQuery = query
183         .rewrite(reader)) {
184       query = rewrittenQuery;
185     }
186     return query;
187   }
188 
189   @Override
190   public Explanation explain(Query query, int docthrows IOException {
191     return query.weight(this).explain(reader, doc);
192   }
193   
194   /**
195    * Each pattern is a result of either simple or a boolean query. The
196    * type number indicates if the query used to retrieve that pattern
197    * was simple or boolean.
198    */
199   private ArrayList<Integer> queryType = new ArrayList<Integer>();
200 
201   /**
202    * Each terms has a frequency.
203    */
204   private ArrayList<Integer> frequencies = new ArrayList<Integer>();
205   
206   /**
207    * Each Integer value in this list is an index of first annotation of
208    * the pattern that matches with the user query.
209    */
210   private ArrayList firstTermPositions = new ArrayList();
211 
212   /**
213    * document numbers
214    */
215   private ArrayList<Integer> documentNumbers = new ArrayList<Integer>();
216 
217   /**
218    * Stores how long each pattern is (in terms of number of
219    * annotations).
220    */
221   private ArrayList<Integer> patternLengths = new ArrayList<Integer>();
222 
223   /**
224    * Sets the firstTermPositions.
225    
226    @param qType
227    @param doc
228    @param positions
229    @param patternLength
230    */
231   public void setFirstTermPositions(int qType, int doc, ArrayList positions,
232           int patternLength, int frequency) {
233     queryType.add(new Integer(qType));
234     firstTermPositions.add(positions);
235     documentNumbers.add(new Integer(doc));
236     patternLengths.add(new Integer(patternLength));
237     frequencies.add(new Integer(frequency));
238   }
239 
240   /**
241    * Initializes all local variables
242    
243    */
244   public void initializeTermPositions() {
245     queryType = new ArrayList<Integer>();
246     firstTermPositions = new ArrayList();
247     documentNumbers = new ArrayList<Integer>();
248     patternLengths = new ArrayList<Integer>();
249     frequencies = new ArrayList<Integer>();
250   }
251 
252   /**
253    * Returns an array of arrayLists where the first list contains
254    * document numbers, second list contains first term positions, third
255    * list contains the pattern lengths and the fourth one contains the
256    * query type for each pattern.
257    */
258   public ArrayList[] getFirstTermPositions() {
259     return new ArrayList[] {documentNumbers, firstTermPositions,
260         patternLengths, queryType, frequencies};
261   }
262 }