Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
ValueSourceQuery.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 Lucene.Net.Index;
20 using IndexReader = Lucene.Net.Index.IndexReader;
21 using TermDocs = Lucene.Net.Index.TermDocs;
22 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
23 using Lucene.Net.Search;
24 
25 namespace Lucene.Net.Search.Function
26 {
27 
28  /// <summary> Expert: A Query that sets the scores of document to the
29  /// values obtained from a <see cref="Lucene.Net.Search.Function.ValueSource">ValueSource</see>.
30  /// <p/>
31  /// This query provides a score for <em>each and every</em> undeleted document in the index.
32  /// <p/>
33  /// The value source can be based on a (cached) value of an indexed field, but it
34  /// can also be based on an external source, e.g. values read from an external database.
35  /// <p/>
36  /// Score is set as: Score(doc,query) = query.getBoost()<sup>2</sup> * valueSource(doc).
37  ///
38  /// <p/><font color="#FF0000">
39  /// WARNING: The status of the <b>Search.Function</b> package is experimental.
40  /// The APIs introduced here might change in the future and will not be
41  /// supported anymore in such a case.</font>
42  /// </summary>
43  [Serializable]
44  public class ValueSourceQuery:Query
45  {
46  internal ValueSource valSrc;
47 
48  /// <summary> Create a value source query</summary>
49  /// <param name="valSrc">provides the values defines the function to be used for scoring
50  /// </param>
52  {
53  this.valSrc = valSrc;
54  }
55 
56  /*(non-Javadoc) <see cref="Lucene.Net.Search.Query.rewrite(Lucene.Net.Index.IndexReader) */
57  public override Query Rewrite(IndexReader reader)
58  {
59  return this;
60  }
61 
62  /*(non-Javadoc) <see cref="Lucene.Net.Search.Query.extractTerms(java.util.Set) */
63  public override void ExtractTerms(System.Collections.Generic.ISet<Term> terms)
64  {
65  // no terms involved here
66  }
67 
68  [Serializable]
69  internal class ValueSourceWeight:Weight
70  {
71  private void InitBlock(ValueSourceQuery enclosingInstance)
72  {
73  this.enclosingInstance = enclosingInstance;
74  }
75  private ValueSourceQuery enclosingInstance;
76  public ValueSourceQuery Enclosing_Instance
77  {
78  get
79  {
80  return enclosingInstance;
81  }
82 
83  }
84  internal Similarity similarity;
85  internal float queryNorm;
86  internal float queryWeight;
87 
88  public ValueSourceWeight(ValueSourceQuery enclosingInstance, Searcher searcher)
89  {
90  InitBlock(enclosingInstance);
91  this.similarity = Enclosing_Instance.GetSimilarity(searcher);
92  }
93 
94  /*(non-Javadoc) <see cref="Lucene.Net.Search.Weight.getQuery() */
95 
96  public override Query Query
97  {
98  get { return Enclosing_Instance; }
99  }
100 
101  /*(non-Javadoc) <see cref="Lucene.Net.Search.Weight.getValue() */
102 
103  public override float Value
104  {
105  get { return queryWeight; }
106  }
107 
108  /*(non-Javadoc) <see cref="Lucene.Net.Search.Weight.sumOfSquaredWeights() */
109 
110  public override float GetSumOfSquaredWeights()
111  {
112  queryWeight = Enclosing_Instance.Boost;
113  return queryWeight*queryWeight;
114  }
115 
116  /*(non-Javadoc) <see cref="Lucene.Net.Search.Weight.normalize(float) */
117  public override void Normalize(float norm)
118  {
119  this.queryNorm = norm;
120  queryWeight *= this.queryNorm;
121  }
122 
123  public override Scorer Scorer(IndexReader reader, bool scoreDocsInOrder, bool topScorer)
124  {
125  return new ValueSourceScorer(enclosingInstance, similarity, reader, this);
126  }
127 
128  /*(non-Javadoc) <see cref="Lucene.Net.Search.Weight.explain(Lucene.Net.Index.IndexReader, int) */
129  public override Explanation Explain(IndexReader reader, int doc)
130  {
131  DocValues vals = enclosingInstance.valSrc.GetValues(reader);
132  float sc = queryWeight*vals.FloatVal(doc);
133 
134  Explanation result = new ComplexExplanation(true, sc, enclosingInstance.ToString() + ", product of:")
135  ;
136  result.AddDetail(vals.Explain(doc));
137  result.AddDetail(new Explanation(enclosingInstance.Boost, "boost"));
138  result.AddDetail(new Explanation(queryNorm, "queryNorm"));
139  return result;
140  }
141  }
142 
143  /// <summary> A scorer that (simply) matches all documents, and scores each document with
144  /// the value of the value soure in effect. As an example, if the value source
145  /// is a (cached) field source, then value of that field in that document will
146  /// be used. (assuming field is indexed for this doc, with a single token.)
147  /// </summary>
148  private class ValueSourceScorer : Scorer
149  {
150  private void InitBlock(ValueSourceQuery enclosingInstance)
151  {
152  this.enclosingInstance = enclosingInstance;
153  }
154  private ValueSourceQuery enclosingInstance;
155  public ValueSourceQuery Enclosing_Instance
156  {
157  get
158  {
159  return enclosingInstance;
160  }
161 
162  }
163  private ValueSourceWeight weight;
164  private float qWeight;
165  private DocValues vals;
166  private TermDocs termDocs;
167  private int doc = -1;
168 
169  // constructor
170  internal ValueSourceScorer(ValueSourceQuery enclosingInstance, Similarity similarity, IndexReader reader, ValueSourceWeight w)
171  : base(similarity)
172  {
173  InitBlock(enclosingInstance);
174  this.weight = w;
175  this.qWeight = w.Value;
176  // this is when/where the values are first created.
177  vals = Enclosing_Instance.valSrc.GetValues(reader);
178  termDocs = reader.TermDocs(null);
179  }
180 
181  public override int NextDoc()
182  {
183  return doc = termDocs.Next() ? termDocs.Doc : NO_MORE_DOCS;
184  }
185 
186  public override int DocID()
187  {
188  return doc;
189  }
190 
191  public override int Advance(int target)
192  {
193  return doc = termDocs.SkipTo(target) ? termDocs.Doc : NO_MORE_DOCS;
194  }
195 
196  /*(non-Javadoc) <see cref="Lucene.Net.Search.Scorer.explain(int) */
197  public override float Score()
198  {
199  return qWeight * vals.FloatVal(termDocs.Doc);
200  }
201  }
202 
203  public override Weight CreateWeight(Searcher searcher)
204  {
205  return new ValueSourceQuery.ValueSourceWeight(this, searcher);
206  }
207 
208  public override System.String ToString(System.String field)
209  {
210  return valSrc.ToString() + ToStringUtils.Boost(Boost);
211  }
212 
213  /// <summary>Returns true if <c>o</c> is equal to this. </summary>
214  public override bool Equals(System.Object o)
215  {
216  if (GetType() != o.GetType())
217  {
218  return false;
219  }
221  return this.Boost == other.Boost && this.valSrc.Equals(other.valSrc);
222  }
223 
224  /// <summary>Returns a hash code value for this object. </summary>
225  public override int GetHashCode()
226  {
227  return (GetType().GetHashCode() + valSrc.GetHashCode()) ^ BitConverter.ToInt32(BitConverter.GetBytes(Boost), 0);
228  }
229 
230  override public System.Object Clone()
231  {
232  return this.MemberwiseClone();
233  }
234  }
235 }