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

搜索引擎

开发平台:

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 MultipleTermPositions = Lucene.Net.Index.MultipleTermPositions;
  19. using Term = Lucene.Net.Index.Term;
  20. using TermPositions = Lucene.Net.Index.TermPositions;
  21. using ToStringUtils = Lucene.Net.Util.ToStringUtils;
  22. namespace Lucene.Net.Search
  23. {
  24. /// <summary> PhrasePrefixQuery is a generalized version of PhraseQuery, with an added
  25. /// method {@link #Add(Term[])}.
  26. /// To use this class, to search for the phrase "Microsoft app*" first use
  27. /// add(Term) on the term "Microsoft", then find all terms that has "app" as
  28. /// prefix using IndexReader.terms(Term), and use PhrasePrefixQuery.add(Term[]
  29. /// terms) to add them to the query.
  30. /// 
  31. /// </summary>
  32. /// <deprecated> use {@link Lucene.Net.search.MultiPhraseQuery} instead
  33. /// </deprecated>
  34. /// <author>  Anders Nielsen
  35. /// </author>
  36. /// <version>  1.0
  37. /// </version>
  38. [Serializable]
  39. public class PhrasePrefixQuery : Query
  40. {
  41. private System.String field;
  42. private System.Collections.ArrayList termArrays = new System.Collections.ArrayList();
  43. private System.Collections.ArrayList positions = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
  44. private int slop = 0;
  45. /// <summary>Sets the phrase slop for this query.</summary>
  46. /// <seealso cref="PhraseQuery.SetSlop(int)">
  47. /// </seealso>
  48. public virtual void  SetSlop(int s)
  49. {
  50. slop = s;
  51. }
  52. /// <summary>Sets the phrase slop for this query.</summary>
  53. /// <seealso cref="PhraseQuery.GetSlop()">
  54. /// </seealso>
  55. public virtual int GetSlop()
  56. {
  57. return slop;
  58. }
  59. /// <summary>Add a single term at the next position in the phrase.</summary>
  60. /// <seealso cref="PhraseQuery.Add(Term)">
  61. /// </seealso>
  62. public virtual void  Add(Term term)
  63. {
  64. Add(new Term[]{term});
  65. }
  66. /// <summary>Add multiple terms at the next position in the phrase.  Any of the terms
  67. /// may match.
  68. /// 
  69. /// </summary>
  70. /// <seealso cref="PhraseQuery.Add(Term)">
  71. /// </seealso>
  72. public virtual void  Add(Term[] terms)
  73. {
  74. int position = 0;
  75. if (positions.Count > 0)
  76. position = ((System.Int32) positions[positions.Count - 1]) + 1;
  77. Add(terms, position);
  78. }
  79. /// <summary> Allows to specify the relative position of terms within the phrase.
  80. /// 
  81. /// </summary>
  82. /// <seealso cref="PhraseQuery.Add(Term, int)">
  83. /// </seealso>
  84. /// <param name="terms">
  85. /// </param>
  86. /// <param name="position">
  87. /// </param>
  88. public virtual void  Add(Term[] terms, int position)
  89. {
  90. if (termArrays.Count == 0)
  91. field = terms[0].Field();
  92. for (int i = 0; i < terms.Length; i++)
  93. {
  94. if (terms[i].Field() != field)
  95. {
  96. throw new System.ArgumentException("All phrase terms must be in the same field (" + field + "): " + terms[i]);
  97. }
  98. }
  99. termArrays.Add(terms);
  100. positions.Add((System.Int32) position);
  101. }
  102. /// <summary> Returns the relative positions of terms in this phrase.</summary>
  103. public virtual int[] GetPositions()
  104. {
  105. int[] result = new int[positions.Count];
  106. for (int i = 0; i < positions.Count; i++)
  107. result[i] = ((System.Int32) positions[i]);
  108. return result;
  109. }
  110. [Serializable]
  111. private class PhrasePrefixWeight : Weight
  112. {
  113. private void  InitBlock(PhrasePrefixQuery enclosingInstance)
  114. {
  115. this.enclosingInstance = enclosingInstance;
  116. }
  117. private PhrasePrefixQuery enclosingInstance;
  118. public PhrasePrefixQuery Enclosing_Instance
  119. {
  120. get
  121. {
  122. return enclosingInstance;
  123. }
  124. }
  125. private Similarity similarity;
  126. private float value_Renamed;
  127. private float idf;
  128. private float queryNorm;
  129. private float queryWeight;
  130. public PhrasePrefixWeight(PhrasePrefixQuery enclosingInstance, Searcher searcher)
  131. {
  132. InitBlock(enclosingInstance);
  133. this.similarity = Enclosing_Instance.GetSimilarity(searcher);
  134. // compute idf
  135. System.Collections.IEnumerator i = Enclosing_Instance.termArrays.GetEnumerator();
  136. while (i.MoveNext())
  137. {
  138. Term[] terms = (Term[]) i.Current;
  139. for (int j = 0; j < terms.Length; j++)
  140. {
  141. idf += Enclosing_Instance.GetSimilarity(searcher).Idf(terms[j], searcher);
  142. }
  143. }
  144. }
  145. public virtual Query GetQuery()
  146. {
  147. return Enclosing_Instance;
  148. }
  149. public virtual float GetValue()
  150. {
  151. return value_Renamed;
  152. }
  153. public virtual float SumOfSquaredWeights()
  154. {
  155. queryWeight = idf * Enclosing_Instance.GetBoost(); // compute query weight
  156. return queryWeight * queryWeight; // square it
  157. }
  158. public virtual void  Normalize(float queryNorm)
  159. {
  160. this.queryNorm = queryNorm;
  161. queryWeight *= queryNorm; // normalize query weight
  162. value_Renamed = queryWeight * idf; // idf for document 
  163. }
  164. public virtual Scorer Scorer(IndexReader reader)
  165. {
  166. if (Enclosing_Instance.termArrays.Count == 0)
  167. // optimize zero-term case
  168. return null;
  169. TermPositions[] tps = new TermPositions[Enclosing_Instance.termArrays.Count];
  170. for (int i = 0; i < tps.Length; i++)
  171. {
  172. Term[] terms = (Term[]) Enclosing_Instance.termArrays[i];
  173. TermPositions p;
  174. if (terms.Length > 1)
  175. p = new MultipleTermPositions(reader, terms);
  176. else
  177. p = reader.TermPositions(terms[0]);
  178. if (p == null)
  179. return null;
  180. tps[i] = p;
  181. }
  182. if (Enclosing_Instance.slop == 0)
  183. return new ExactPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, reader.Norms(Enclosing_Instance.field));
  184. else
  185. return new SloppyPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
  186. }
  187. public virtual Explanation Explain(IndexReader reader, int doc)
  188. {
  189. Explanation result = new Explanation();
  190. result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
  191. Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");
  192. // explain query weight
  193. Explanation queryExpl = new Explanation();
  194. queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
  195. Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
  196. if (Enclosing_Instance.GetBoost() != 1.0f)
  197. queryExpl.AddDetail(boostExpl);
  198. queryExpl.AddDetail(idfExpl);
  199. Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
  200. queryExpl.AddDetail(queryNormExpl);
  201. queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
  202. result.AddDetail(queryExpl);
  203. // explain field weight
  204. Explanation fieldExpl = new Explanation();
  205. fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");
  206. Explanation tfExpl = Scorer(reader).Explain(doc);
  207. fieldExpl.AddDetail(tfExpl);
  208. fieldExpl.AddDetail(idfExpl);
  209. Explanation fieldNormExpl = new Explanation();
  210. byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
  211. float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):0.0f;
  212. fieldNormExpl.SetValue(fieldNorm);
  213. fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
  214. fieldExpl.AddDetail(fieldNormExpl);
  215. fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
  216. result.AddDetail(fieldExpl);
  217. // combine them
  218. result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
  219. if (queryExpl.GetValue() == 1.0f)
  220. return fieldExpl;
  221. return result;
  222. }
  223. }
  224. protected internal override Weight CreateWeight(Searcher searcher)
  225. {
  226. if (termArrays.Count == 1)
  227. {
  228. // optimize one-term case
  229. Term[] terms = (Term[]) termArrays[0];
  230. BooleanQuery boq = new BooleanQuery(true);
  231. for (int i = 0; i < terms.Length; i++)
  232. {
  233. boq.Add(new TermQuery(terms[i]), BooleanClause.Occur.SHOULD);
  234. }
  235. boq.SetBoost(GetBoost());
  236. return boq.CreateWeight(searcher);
  237. }
  238. return new PhrasePrefixWeight(this, searcher);
  239. }
  240. /// <summary>Prints a user-readable version of this query. </summary>
  241. public override System.String ToString(System.String f)
  242. {
  243. System.Text.StringBuilder buffer = new System.Text.StringBuilder();
  244. if (!field.Equals(f))
  245. {
  246. buffer.Append(field);
  247. buffer.Append(":");
  248. }
  249. buffer.Append(""");
  250. System.Collections.IEnumerator i = termArrays.GetEnumerator();
  251. while (i.MoveNext())
  252. {
  253. Term[] terms = (Term[]) i.Current;
  254. buffer.Append(terms[0].Text() + (terms.Length > 1?"*":""));
  255. if (i.MoveNext())
  256. buffer.Append(" ");
  257. }
  258. buffer.Append(""");
  259. if (slop != 0)
  260. {
  261. buffer.Append("~");
  262. buffer.Append(slop);
  263. }
  264. buffer.Append(ToStringUtils.Boost(GetBoost()));
  265. return buffer.ToString();
  266. }
  267.         // {{Aroush-1.9}} Do we need this?!
  268. override public System.Object Clone()
  269. {
  270. return null;
  271. }
  272. }
  273. }