pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / search / function / CustomScoreProvider.java
1 package org.apache.lucene.search.function;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22 import org.apache.lucene.index.IndexReader;
23 import org.apache.lucene.search.Explanation;
24 import org.apache.lucene.search.FieldCache; // for javadocs
25
26 /**
27  * An instance of this subclass should be returned by
28  * {@link CustomScoreQuery#getCustomScoreProvider}, if you want
29  * to modify the custom score calculation of a {@link CustomScoreQuery}.
30  * <p>Since Lucene 2.9, queries operate on each segment of an index separately,
31  * so the protected {@link #reader} field can be used to resolve doc IDs,
32  * as the supplied <code>doc</code> ID is per-segment and without knowledge
33  * of the IndexReader you cannot access the document or {@link FieldCache}.
34  * 
35  * @lucene.experimental
36  * @since 2.9.2
37  */
38 public class CustomScoreProvider {
39
40   protected final IndexReader reader;
41
42   /**
43    * Creates a new instance of the provider class for the given {@link IndexReader}.
44    */
45   public CustomScoreProvider(IndexReader reader) {
46     this.reader = reader;
47   }
48
49   /**
50    * Compute a custom score by the subQuery score and a number of 
51    * {@link ValueSourceQuery} scores.
52    * <p> 
53    * Subclasses can override this method to modify the custom score.  
54    * <p>
55    * If your custom scoring is different than the default herein you 
56    * should override at least one of the two customScore() methods.
57    * If the number of ValueSourceQueries is always &lt; 2 it is 
58    * sufficient to override the other 
59    * {@link #customScore(int, float, float) customScore()} 
60    * method, which is simpler. 
61    * <p>
62    * The default computation herein is a multiplication of given scores:
63    * <pre>
64    *     ModifiedScore = valSrcScore * valSrcScores[0] * valSrcScores[1] * ...
65    * </pre>
66    * 
67    * @param doc id of scored doc. 
68    * @param subQueryScore score of that doc by the subQuery.
69    * @param valSrcScores scores of that doc by the ValueSourceQuery.
70    * @return custom score.
71    */
72   public float customScore(int doc, float subQueryScore, float valSrcScores[]) throws IOException {
73     if (valSrcScores.length == 1) {
74       return customScore(doc, subQueryScore, valSrcScores[0]);
75     }
76     if (valSrcScores.length == 0) {
77       return customScore(doc, subQueryScore, 1);
78     }
79     float score = subQueryScore;
80     for(int i = 0; i < valSrcScores.length; i++) {
81       score *= valSrcScores[i];
82     }
83     return score;
84   }
85
86   /**
87    * Compute a custom score by the subQuery score and the ValueSourceQuery score.
88    * <p> 
89    * Subclasses can override this method to modify the custom score.
90    * <p>
91    * If your custom scoring is different than the default herein you 
92    * should override at least one of the two customScore() methods.
93    * If the number of ValueSourceQueries is always &lt; 2 it is 
94    * sufficient to override this customScore() method, which is simpler. 
95    * <p>
96    * The default computation herein is a multiplication of the two scores:
97    * <pre>
98    *     ModifiedScore = subQueryScore * valSrcScore
99    * </pre>
100    *
101    * @param doc id of scored doc. 
102    * @param subQueryScore score of that doc by the subQuery.
103    * @param valSrcScore score of that doc by the ValueSourceQuery.
104    * @return custom score.
105    */
106   public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException {
107     return subQueryScore * valSrcScore;
108   }
109
110   /**
111    * Explain the custom score.
112    * Whenever overriding {@link #customScore(int, float, float[])}, 
113    * this method should also be overridden to provide the correct explanation
114    * for the part of the custom scoring.
115    *  
116    * @param doc doc being explained.
117    * @param subQueryExpl explanation for the sub-query part.
118    * @param valSrcExpls explanation for the value source part.
119    * @return an explanation for the custom score
120    */
121   public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpls[]) throws IOException {
122     if (valSrcExpls.length == 1) {
123       return customExplain(doc, subQueryExpl, valSrcExpls[0]);
124     }
125     if (valSrcExpls.length == 0) {
126       return subQueryExpl;
127     }
128     float valSrcScore = 1;
129     for (int i = 0; i < valSrcExpls.length; i++) {
130       valSrcScore *= valSrcExpls[i].getValue();
131     }
132     Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:");
133     exp.addDetail(subQueryExpl);
134     for (int i = 0; i < valSrcExpls.length; i++) {
135       exp.addDetail(valSrcExpls[i]);
136     }
137     return exp;
138   }
139   
140   /**
141    * Explain the custom score.
142    * Whenever overriding {@link #customScore(int, float, float)}, 
143    * this method should also be overridden to provide the correct explanation
144    * for the part of the custom scoring.
145    *  
146    * @param doc doc being explained.
147    * @param subQueryExpl explanation for the sub-query part.
148    * @param valSrcExpl explanation for the value source part.
149    * @return an explanation for the custom score
150    */
151   public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) throws IOException {
152     float valSrcScore = 1;
153     if (valSrcExpl != null) {
154       valSrcScore *= valSrcExpl.getValue();
155     }
156     Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:");
157     exp.addDetail(subQueryExpl);
158     exp.addDetail(valSrcExpl);
159     return exp;
160   }
161
162 }