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

搜索引擎

开发平台:

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 IndexReader = Lucene.Net.Index.IndexReader;
  18. using Term = Lucene.Net.Index.Term;
  19. using TermDocs = Lucene.Net.Index.TermDocs;
  20. using TermEnum = Lucene.Net.Index.TermEnum;
  21. namespace Lucene.Net.Search
  22. {
  23. /// <summary> A Filter that restricts search results to a range of values in a given
  24. /// field.
  25. /// 
  26. /// <p>
  27. /// This code borrows heavily from {@link RangeQuery}, but is implemented as a Filter
  28. /// (much like {@link DateFilter}).
  29. /// </p>
  30. /// </summary>
  31. [Serializable]
  32. public class RangeFilter : Filter
  33. {
  34. private System.String fieldName;
  35. private System.String lowerTerm;
  36. private System.String upperTerm;
  37. private bool includeLower;
  38. private bool includeUpper;
  39. /// <param name="fieldName">The field this range applies to
  40. /// </param>
  41. /// <param name="lowerTerm">The lower bound on this range
  42. /// </param>
  43. /// <param name="upperTerm">The upper bound on this range
  44. /// </param>
  45. /// <param name="includeLower">Does this range include the lower bound?
  46. /// </param>
  47. /// <param name="includeUpper">Does this range include the upper bound?
  48. /// </param>
  49. /// <throws>  IllegalArgumentException if both terms are null or if </throws>
  50. /// <summary>  lowerTerm is null and includeLower is true (similar for upperTerm
  51. /// and includeUpper)
  52. /// </summary>
  53. public RangeFilter(System.String fieldName, System.String lowerTerm, System.String upperTerm, bool includeLower, bool includeUpper)
  54. {
  55. this.fieldName = fieldName;
  56. this.lowerTerm = lowerTerm;
  57. this.upperTerm = upperTerm;
  58. this.includeLower = includeLower;
  59. this.includeUpper = includeUpper;
  60. if (null == lowerTerm && null == upperTerm)
  61. {
  62. throw new System.ArgumentException("At least one value must be non-null");
  63. }
  64. if (includeLower && null == lowerTerm)
  65. {
  66. throw new System.ArgumentException("The lower bound must be non-null to be inclusive");
  67. }
  68. if (includeUpper && null == upperTerm)
  69. {
  70. throw new System.ArgumentException("The upper bound must be non-null to be inclusive");
  71. }
  72. }
  73. /// <summary> Constructs a filter for field <code>fieldName</code> matching
  74. /// less than or equal to <code>upperTerm</code>.
  75. /// </summary>
  76. public static RangeFilter Less(System.String fieldName, System.String upperTerm)
  77. {
  78. return new RangeFilter(fieldName, null, upperTerm, false, true);
  79. }
  80. /// <summary> Constructs a filter for field <code>fieldName</code> matching
  81. /// greater than or equal to <code>lowerTerm</code>.
  82. /// </summary>
  83. public static RangeFilter More(System.String fieldName, System.String lowerTerm)
  84. {
  85. return new RangeFilter(fieldName, lowerTerm, null, true, false);
  86. }
  87. /// <summary> Returns a BitSet with true for documents which should be
  88. /// permitted in search results, and false for those that should
  89. /// not.
  90. /// </summary>
  91. public override System.Collections.BitArray Bits(IndexReader reader)
  92. {
  93. System.Collections.BitArray bits = new System.Collections.BitArray((reader.MaxDoc() % 64 == 0?reader.MaxDoc() / 64:reader.MaxDoc() / 64 + 1) * 64);
  94. TermEnum enumerator = (null != lowerTerm?reader.Terms(new Term(fieldName, lowerTerm)):reader.Terms(new Term(fieldName, "")));
  95. try
  96. {
  97. if (enumerator.Term() == null)
  98. {
  99. return bits;
  100. }
  101. bool checkLower = false;
  102. if (!includeLower)
  103.     // make adjustments to set to exclusive
  104. checkLower = true;
  105. TermDocs termDocs = reader.TermDocs();
  106. try
  107. {
  108. do 
  109. {
  110. Term term = enumerator.Term();
  111. if (term != null && term.Field().Equals(fieldName))
  112. {
  113. if (!checkLower || null == lowerTerm || String.CompareOrdinal(term.Text(), lowerTerm) > 0)
  114. {
  115. checkLower = false;
  116. if (upperTerm != null)
  117. {
  118. int compare = String.CompareOrdinal(upperTerm, term.Text());
  119. /* if beyond the upper term, or is exclusive and
  120. * this is equal to the upper term, break out */
  121. if ((compare < 0) || (!includeUpper && compare == 0))
  122. {
  123. break;
  124. }
  125. }
  126. /* we have a good term, find the docs */
  127. termDocs.Seek(enumerator.Term());
  128. while (termDocs.Next())
  129. {
  130. bits.Set(termDocs.Doc(), true);
  131. }
  132. }
  133. }
  134. else
  135. {
  136. break;
  137. }
  138. }
  139. while (enumerator.Next());
  140. }
  141. finally
  142. {
  143. termDocs.Close();
  144. }
  145. }
  146. finally
  147. {
  148. enumerator.Close();
  149. }
  150. return bits;
  151. }
  152. public override System.String ToString()
  153. {
  154. System.Text.StringBuilder buffer = new System.Text.StringBuilder();
  155. buffer.Append(fieldName);
  156. buffer.Append(":");
  157. buffer.Append(includeLower?"[":"{");
  158. if (null != lowerTerm)
  159. {
  160. buffer.Append(lowerTerm);
  161. }
  162. buffer.Append("-");
  163. if (null != upperTerm)
  164. {
  165. buffer.Append(upperTerm);
  166. }
  167. buffer.Append(includeUpper ? "]" : "}");
  168. return buffer.ToString();
  169. }
  170. /// <summary>Returns true if <code>o</code> is equal to this. </summary>
  171. public  override bool Equals(System.Object o)
  172. {
  173. if (this == o)
  174. return true;
  175. if (!(o is RangeFilter))
  176. return false;
  177. RangeFilter other = (RangeFilter) o;
  178. if (!this.fieldName.Equals(other.fieldName) || this.includeLower != other.includeLower || this.includeUpper != other.includeUpper)
  179. {
  180. return false;
  181. }
  182. if (this.lowerTerm != null ? !this.lowerTerm.Equals(other.lowerTerm) : other.lowerTerm != null)
  183. return false;
  184. if (this.upperTerm != null ? !this.upperTerm.Equals(other.upperTerm) : other.upperTerm != null)
  185. return false;
  186. return true;
  187. }
  188. /// <summary>Returns a hash code value for this object.</summary>
  189. public override int GetHashCode()
  190. {
  191. int h = fieldName.GetHashCode();
  192. h ^= (lowerTerm != null ? lowerTerm.GetHashCode() : unchecked((int) 0xB6ECE882));           // {{Aroush-1.9}} is this OK?!
  193. h = (h << 1) | (SupportClass.Number.URShift(h, 31)); // rotate to distinguish lower from upper
  194. h ^= (upperTerm != null ? (upperTerm.GetHashCode()) : unchecked((int) 0x91BEC2C2));         // {{Aroush-1.9}} is this OK?!
  195. h ^= (includeLower ? unchecked((int) 0xD484B933) : 0) ^ (includeUpper ? 0x6AE423AC : 0);    // {{Aroush-1.9}} is this OK?!
  196. return h;
  197. }
  198. }
  199. }