Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
IndexSearcher.cs
Go to the documentation of this file.
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 using System;
19 using System.Linq;
20 using Lucene.Net.Index;
21 using Document = Lucene.Net.Documents.Document;
22 using FieldSelector = Lucene.Net.Documents.FieldSelector;
24 using IndexReader = Lucene.Net.Index.IndexReader;
25 using Term = Lucene.Net.Index.Term;
26 using Directory = Lucene.Net.Store.Directory;
27 using ReaderUtil = Lucene.Net.Util.ReaderUtil;
28 
29 namespace Lucene.Net.Search
30 {
31 
46  [Serializable]
47  public class IndexSearcher : Searcher
48  {
49  internal IndexReader reader;
50  private bool closeReader;
51  private bool isDisposed;
52 
53  // NOTE: these members might change in incompatible ways
54  // in the next release
55  private IndexReader[] subReaders;
56  private int[] docStarts;
57 
62  public IndexSearcher(Directory path)
63  : this(IndexReader.Open(path, true), true)
64  {
65  }
66 
80  public IndexSearcher(Directory path, bool readOnly):this(IndexReader.Open(path, readOnly), true)
81  {
82  }
83 
92  public IndexSearcher(IndexReader r):this(r, false)
93  {
94  }
95 
104  public IndexSearcher(IndexReader reader, IndexReader[] subReaders, int[] docStarts)
105  {
106  this.reader = reader;
107  this.subReaders = subReaders;
108  this.docStarts = docStarts;
109  this.closeReader = false;
110  }
111 
112  private IndexSearcher(IndexReader r, bool closeReader)
113  {
114  reader = r;
115  this.closeReader = closeReader;
116 
117  System.Collections.Generic.IList<IndexReader> subReadersList = new System.Collections.Generic.List<IndexReader>();
118  GatherSubReaders(subReadersList, reader);
119  subReaders = subReadersList.ToArray();
120  docStarts = new int[subReaders.Length];
121  int maxDoc = 0;
122  for (int i = 0; i < subReaders.Length; i++)
123  {
124  docStarts[i] = maxDoc;
125  maxDoc += subReaders[i].MaxDoc;
126  }
127  }
128 
129  protected internal virtual void GatherSubReaders(System.Collections.Generic.IList<IndexReader> allSubReaders, IndexReader r)
130  {
131  ReaderUtil.GatherSubReaders(allSubReaders, r);
132  }
133 
135  public virtual IndexReader IndexReader
136  {
137  get { return reader; }
138  }
139 
140  protected override void Dispose(bool disposing)
141  {
142  if (isDisposed) return;
143 
144  if (disposing)
145  {
146  if (closeReader)
147  reader.Close();
148  }
149 
150  isDisposed = true;
151  }
152 
153  // inherit javadoc
154  public override int DocFreq(Term term)
155  {
156  return reader.DocFreq(term);
157  }
158 
159  // inherit javadoc
160  public override Document Doc(int i)
161  {
162  return reader.Document(i);
163  }
164 
165  // inherit javadoc
166  public override Document Doc(int i, FieldSelector fieldSelector)
167  {
168  return reader.Document(i, fieldSelector);
169  }
170 
171  // inherit javadoc
172  public override int MaxDoc
173  {
174  get { return reader.MaxDoc; }
175  }
176 
177  // inherit javadoc
178  public override TopDocs Search(Weight weight, Filter filter, int nDocs)
179  {
180 
181  if (nDocs <= 0)
182  {
183  throw new System.ArgumentException("nDocs must be > 0");
184  }
185  nDocs = Math.Min(nDocs, reader.MaxDoc);
186 
188  Search(weight, filter, collector);
189  return collector.TopDocs();
190  }
191 
192  public override TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort)
193  {
194  return Search(weight, filter, nDocs, sort, true);
195  }
196 
207  public virtual TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort, bool fillFields)
208  {
209  nDocs = Math.Min(nDocs, reader.MaxDoc);
210 
211  TopFieldCollector collector2 = TopFieldCollector.Create(sort, nDocs, fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight.GetScoresDocsOutOfOrder());
212  Search(weight, filter, collector2);
213  return (TopFieldDocs) collector2.TopDocs();
214  }
215 
216  public override void Search(Weight weight, Filter filter, Collector collector)
217  {
218 
219  if (filter == null)
220  {
221  for (int i = 0; i < subReaders.Length; i++)
222  {
223  // search each subreader
224  collector.SetNextReader(subReaders[i], docStarts[i]);
225  Scorer scorer = weight.Scorer(subReaders[i], !collector.AcceptsDocsOutOfOrder, true);
226  if (scorer != null)
227  {
228  scorer.Score(collector);
229  }
230  }
231  }
232  else
233  {
234  for (int i = 0; i < subReaders.Length; i++)
235  {
236  // search each subreader
237  collector.SetNextReader(subReaders[i], docStarts[i]);
238  SearchWithFilter(subReaders[i], weight, filter, collector);
239  }
240  }
241  }
242 
243  private void SearchWithFilter(IndexReader reader, Weight weight, Filter filter, Collector collector)
244  {
245 
246  System.Diagnostics.Debug.Assert(filter != null);
247 
248  Scorer scorer = weight.Scorer(reader, true, false);
249  if (scorer == null)
250  {
251  return ;
252  }
253 
254  int docID = scorer.DocID();
255  System.Diagnostics.Debug.Assert(docID == - 1 || docID == DocIdSetIterator.NO_MORE_DOCS);
256 
257  // CHECKME: use ConjunctionScorer here?
258  DocIdSet filterDocIdSet = filter.GetDocIdSet(reader);
259  if (filterDocIdSet == null)
260  {
261  // this means the filter does not accept any documents.
262  return ;
263  }
264 
265  DocIdSetIterator filterIter = filterDocIdSet.Iterator();
266  if (filterIter == null)
267  {
268  // this means the filter does not accept any documents.
269  return ;
270  }
271  int filterDoc = filterIter.NextDoc();
272  int scorerDoc = scorer.Advance(filterDoc);
273 
274  collector.SetScorer(scorer);
275  while (true)
276  {
277  if (scorerDoc == filterDoc)
278  {
279  // Check if scorer has exhausted, only before collecting.
280  if (scorerDoc == DocIdSetIterator.NO_MORE_DOCS)
281  {
282  break;
283  }
284  collector.Collect(scorerDoc);
285  filterDoc = filterIter.NextDoc();
286  scorerDoc = scorer.Advance(filterDoc);
287  }
288  else if (scorerDoc > filterDoc)
289  {
290  filterDoc = filterIter.Advance(scorerDoc);
291  }
292  else
293  {
294  scorerDoc = scorer.Advance(filterDoc);
295  }
296  }
297  }
298 
299  public override Query Rewrite(Query original)
300  {
301  Query query = original;
302  for (Query rewrittenQuery = query.Rewrite(reader); rewrittenQuery != query; rewrittenQuery = query.Rewrite(reader))
303  {
304  query = rewrittenQuery;
305  }
306  return query;
307  }
308 
309  public override Explanation Explain(Weight weight, int doc)
310  {
311  int n = ReaderUtil.SubIndex(doc, docStarts);
312  int deBasedDoc = doc - docStarts[n];
313 
314  return weight.Explain(subReaders[n], deBasedDoc);
315  }
316 
317  private bool fieldSortDoTrackScores;
318  private bool fieldSortDoMaxScore;
319 
332  public virtual void SetDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore)
333  {
334  fieldSortDoTrackScores = doTrackScores;
335  fieldSortDoMaxScore = doMaxScore;
336  }
337 
338  public IndexReader reader_ForNUnit
339  {
340  get { return reader; }
341  }
342  }
343 }