IndexSearcher.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:9k
源码类别:

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2004 The Apache Software Foundation
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. using System;
  17. using Document = Lucene.Net.Documents.Document;
  18. using IndexReader = Lucene.Net.Index.IndexReader;
  19. using Term = Lucene.Net.Index.Term;
  20. using Directory = Lucene.Net.Store.Directory;
  21. namespace Lucene.Net.Search
  22. {
  23. /// <summary>Implements search over a single IndexReader.
  24. /// 
  25. /// <p>Applications usually need only call the inherited {@link #Search(Query)}
  26. /// or {@link #Search(Query,Filter)} methods. For performance reasons it is 
  27. /// recommended to open only one IndexSearcher and use it for all of your searches.
  28. /// 
  29. /// <p>Note that you can only access Hits from an IndexSearcher as long as it is
  30. /// not yet closed, otherwise an IOException will be thrown. 
  31. /// </summary>
  32. public class IndexSearcher : Searcher
  33. {
  34. private class AnonymousClassHitCollector:HitCollector
  35. {
  36. public AnonymousClassHitCollector(System.Collections.BitArray bits, int[] totalHits, Lucene.Net.Search.HitQueue hq, int nDocs, IndexSearcher enclosingInstance)
  37. {
  38. InitBlock(bits, totalHits, hq, nDocs, enclosingInstance);
  39. }
  40. private void  InitBlock(System.Collections.BitArray bits, int[] totalHits, Lucene.Net.Search.HitQueue hq, int nDocs, IndexSearcher enclosingInstance)
  41. {
  42. this.bits = bits;
  43. this.totalHits = totalHits;
  44. this.hq = hq;
  45. this.nDocs = nDocs;
  46. this.enclosingInstance = enclosingInstance;
  47. }
  48. private System.Collections.BitArray bits;
  49. private int[] totalHits;
  50. private Lucene.Net.Search.HitQueue hq;
  51. private int nDocs;
  52. private IndexSearcher enclosingInstance;
  53. public IndexSearcher Enclosing_Instance
  54. {
  55. get
  56. {
  57. return enclosingInstance;
  58. }
  59. }
  60. private float minScore = 0.0f;
  61. public override void  Collect(int doc, float score)
  62. {
  63. if (score > 0.0f && (bits == null || bits.Get(doc)))
  64. {
  65. // skip docs not in bits
  66. totalHits[0]++;
  67. if (hq.Size() < nDocs || score >= minScore)
  68. {
  69. hq.Insert(new ScoreDoc(doc, score));
  70. minScore = ((ScoreDoc) hq.Top()).score; // maintain minScore
  71. }
  72. }
  73. }
  74. }
  75. private class AnonymousClassHitCollector1 : HitCollector
  76. {
  77. public AnonymousClassHitCollector1(System.Collections.BitArray bits, int[] totalHits, Lucene.Net.Search.FieldSortedHitQueue hq, IndexSearcher enclosingInstance)
  78. {
  79. InitBlock(bits, totalHits, hq, enclosingInstance);
  80. }
  81. private void  InitBlock(System.Collections.BitArray bits, int[] totalHits, Lucene.Net.Search.FieldSortedHitQueue hq, IndexSearcher enclosingInstance)
  82. {
  83. this.bits = bits;
  84. this.totalHits = totalHits;
  85. this.hq = hq;
  86. this.enclosingInstance = enclosingInstance;
  87. }
  88. private System.Collections.BitArray bits;
  89. private int[] totalHits;
  90. private Lucene.Net.Search.FieldSortedHitQueue hq;
  91. private IndexSearcher enclosingInstance;
  92. public IndexSearcher Enclosing_Instance
  93. {
  94. get
  95. {
  96. return enclosingInstance;
  97. }
  98. }
  99. public override void  Collect(int doc, float score)
  100. {
  101. if (score > 0.0f && (bits == null || bits.Get(doc)))
  102. {
  103. // skip docs not in bits
  104. totalHits[0]++;
  105. hq.Insert(new FieldDoc(doc, score));
  106. }
  107. }
  108. }
  109. private class AnonymousClassHitCollector2 : HitCollector
  110. {
  111. public AnonymousClassHitCollector2(System.Collections.BitArray bits, Lucene.Net.Search.HitCollector results, IndexSearcher enclosingInstance)
  112. {
  113. InitBlock(bits, results, enclosingInstance);
  114. }
  115. private void  InitBlock(System.Collections.BitArray bits, Lucene.Net.Search.HitCollector results, IndexSearcher enclosingInstance)
  116. {
  117. this.bits = bits;
  118. this.results = results;
  119. this.enclosingInstance = enclosingInstance;
  120. }
  121. private System.Collections.BitArray bits;
  122. private Lucene.Net.Search.HitCollector results;
  123. private IndexSearcher enclosingInstance;
  124. public IndexSearcher Enclosing_Instance
  125. {
  126. get
  127. {
  128. return enclosingInstance;
  129. }
  130. }
  131. public override void  Collect(int doc, float score)
  132. {
  133. if (bits.Get(doc))
  134. {
  135. // skip docs not in bits
  136. results.Collect(doc, score);
  137. }
  138. }
  139. }
  140. internal IndexReader reader;
  141. private bool closeReader;
  142. /// <summary>Creates a searcher searching the index in the named directory. </summary>
  143. public IndexSearcher(System.String path) : this(IndexReader.Open(path), true)
  144. {
  145. }
  146. /// <summary>Creates a searcher searching the index in the provided directory. </summary>
  147. public IndexSearcher(Directory directory) : this(IndexReader.Open(directory), true)
  148. {
  149. }
  150. /// <summary>Creates a searcher searching the provided index. </summary>
  151. public IndexSearcher(IndexReader r) : this(r, false)
  152. {
  153. }
  154. private IndexSearcher(IndexReader r, bool closeReader)
  155. {
  156. reader = r;
  157. this.closeReader = closeReader;
  158. }
  159. /// <summary>Return the {@link IndexReader} this searches. </summary>
  160. public virtual IndexReader GetIndexReader()
  161. {
  162. return reader;
  163. }
  164. /// <summary> Note that the underlying IndexReader is not closed, if
  165. /// IndexSearcher was constructed with IndexSearcher(IndexReader r).
  166. /// If the IndexReader was supplied implicitly by specifying a directory, then
  167. /// the IndexReader gets closed.
  168. /// </summary>
  169. public override void  Close()
  170. {
  171. if (closeReader)
  172. reader.Close();
  173. }
  174. // inherit javadoc
  175. public override int DocFreq(Term term)
  176. {
  177. return reader.DocFreq(term);
  178. }
  179. // inherit javadoc
  180. public override Document Doc(int i)
  181. {
  182. return reader.Document(i);
  183. }
  184. // inherit javadoc
  185. public override int MaxDoc()
  186. {
  187. return reader.MaxDoc();
  188. }
  189. // inherit javadoc
  190. public override TopDocs Search(Weight weight, Filter filter, int nDocs)
  191. {
  192. if (nDocs <= 0)
  193.     // null might be returned from hq.top() below.
  194. throw new System.ArgumentException("nDocs must be > 0");
  195. Scorer scorer = weight.Scorer(reader);
  196. if (scorer == null)
  197. return new TopDocs(0, new ScoreDoc[0], System.Single.NegativeInfinity);
  198. System.Collections.BitArray bits = filter != null?filter.Bits(reader):null;
  199. HitQueue hq = new HitQueue(nDocs);
  200. int[] totalHits = new int[1];
  201. scorer.Score(new AnonymousClassHitCollector(bits, totalHits, hq, nDocs, this));
  202. ScoreDoc[] scoreDocs = new ScoreDoc[hq.Size()];
  203. for (int i = hq.Size() - 1; i >= 0; i--)
  204.     // put docs in array
  205. scoreDocs[i] = (ScoreDoc) hq.Pop();
  206. float maxScore = (totalHits[0] == 0) ? System.Single.NegativeInfinity : scoreDocs[0].score;
  207. return new TopDocs(totalHits[0], scoreDocs, maxScore);
  208. }
  209. // inherit javadoc
  210. public override TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort)
  211. {
  212. Scorer scorer = weight.Scorer(reader);
  213. if (scorer == null)
  214. return new TopFieldDocs(0, new ScoreDoc[0], sort.fields, System.Single.NegativeInfinity);
  215. System.Collections.BitArray bits = filter != null?filter.Bits(reader):null;
  216. FieldSortedHitQueue hq = new FieldSortedHitQueue(reader, sort.fields, nDocs);
  217. int[] totalHits = new int[1];
  218. scorer.Score(new AnonymousClassHitCollector1(bits, totalHits, hq, this));
  219. ScoreDoc[] scoreDocs = new ScoreDoc[hq.Size()];
  220. for (int i = hq.Size() - 1; i >= 0; i--)
  221. // put docs in array
  222. scoreDocs[i] = hq.FillFields((FieldDoc) hq.Pop());
  223. return new TopFieldDocs(totalHits[0], scoreDocs, hq.GetFields(), hq.GetMaxScore());
  224. }
  225. // inherit javadoc
  226. public override void  Search(Weight weight, Filter filter, HitCollector results)
  227. {
  228. HitCollector collector = results;
  229. if (filter != null)
  230. {
  231. System.Collections.BitArray bits = filter.Bits(reader);
  232. collector = new AnonymousClassHitCollector2(bits, results, this);
  233. }
  234. Scorer scorer = weight.Scorer(reader);
  235. if (scorer == null)
  236. return ;
  237. scorer.Score(collector);
  238. }
  239. public override Query Rewrite(Query original)
  240. {
  241. Query query = original;
  242. for (Query rewrittenQuery = query.Rewrite(reader); rewrittenQuery != query; rewrittenQuery = query.Rewrite(reader))
  243. {
  244. query = rewrittenQuery;
  245. }
  246. return query;
  247. }
  248. public override Explanation Explain(Weight weight, int doc)
  249. {
  250. return weight.Explain(reader, doc);
  251. }
  252. }
  253. }