You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by do...@apache.org on 2007/12/13 07:28:27 UTC
svn commit: r603837 - in /lucene/java/trunk: ./
src/java/org/apache/lucene/search/function/
src/test/org/apache/lucene/search/function/
Author: doronc
Date: Wed Dec 12 22:28:27 2007
New Revision: 603837
URL: http://svn.apache.org/viewvc?rev=603837&view=rev
Log:
LUCENE-1019: CustomScoreQuery enhanced to support multiple ValueSource queries.
Modified:
lucene/java/trunk/CHANGES.txt
lucene/java/trunk/src/java/org/apache/lucene/search/function/CustomScoreQuery.java
lucene/java/trunk/src/test/org/apache/lucene/search/function/FunctionTestSetup.java
lucene/java/trunk/src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java
Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=603837&r1=603836&r2=603837&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Wed Dec 12 22:28:27 2007
@@ -241,6 +241,9 @@
10. LUCENE-1073: Created SnapshotDeletionPolicy to facilitate taking a
live backup of an index without pausing indexing. (Mike
McCandless)
+
+11. LUCENE-1019: CustomScoreQuery enhanced to support multiple
+ ValueSource queries. (Kyle Maxwell via Doron Cohen)
Optimizations
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/function/CustomScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/function/CustomScoreQuery.java?rev=603837&r1=603836&r2=603837&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/function/CustomScoreQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/function/CustomScoreQuery.java Wed Dec 12 22:28:27 2007
@@ -31,10 +31,10 @@
import org.apache.lucene.util.ToStringUtils;
/**
- * Query that sets document score as a programmatic function of (up to) two (sub) scores.
+ * Query that sets document score as a programmatic function of several (sub) scores.
* <ol>
* <li>the score of its subQuery (any query)</li>
- * <li>(optional) the score of its ValueSourtceQuery,
+ * <li>(optional) the score of its ValueSourtceQuery (or queries),
* for most simple/convineient use case this query would be a
* {@link org.apache.lucene.search.function.FieldScoreQuery FieldScoreQuery}</li>
* </ol>
@@ -48,7 +48,7 @@
public class CustomScoreQuery extends Query {
private Query subQuery;
- private ValueSourceQuery valSrcQuery; // optional, can be null
+ private ValueSourceQuery[] valSrcQueries; // never null (empty array if there are no valSrcQueries).
private boolean strict = false; // if true, valueSource part of query does not take part in weights normalization.
/**
@@ -56,7 +56,7 @@
* @param subQuery the sub query whose scored is being customed. Must not be null.
*/
public CustomScoreQuery(Query subQuery) {
- this(subQuery,null);
+ this(subQuery, new ValueSourceQuery[0]);
}
/**
@@ -68,17 +68,31 @@
* This parameter is optional - it can be null.
*/
public CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
+ this(subQuery, valSrcQuery!=null ? // don't want an array that contains a single null..
+ new ValueSourceQuery[] {valSrcQuery} : new ValueSourceQuery[0]);
+ }
+
+ /**
+ * Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}.
+ * @param subQuery the sub query whose score is being customed. Must not be null.
+ * @param valSrcQueries value source queries whose scores are used in the custom score
+ * computation. For most simple/convineient use case these would be
+ * {@link org.apache.lucene.search.function.FieldScoreQuery FieldScoreQueries}.
+ * This parameter is optional - it can be null or even an empty array.
+ */
+ public CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQueries[]) {
super();
this.subQuery = subQuery;
- this.valSrcQuery = valSrcQuery;
- if (subQuery == null) throw new IllegalArgumentException("<subqyery> must not be null!");
+ this.valSrcQueries = valSrcQueries!=null?
+ valSrcQueries : new ValueSourceQuery[0];
+ if (subQuery == null) throw new IllegalArgumentException("<subquery> must not be null!");
}
/*(non-Javadoc) @see org.apache.lucene.search.Query#rewrite(org.apache.lucene.index.IndexReader) */
public Query rewrite(IndexReader reader) throws IOException {
subQuery = subQuery.rewrite(reader);
- if (valSrcQuery!=null) {
- valSrcQuery = (ValueSourceQuery) valSrcQuery.rewrite(reader);
+ for(int i = 0; i < valSrcQueries.length; i++) {
+ valSrcQueries[i] = (ValueSourceQuery) valSrcQueries[i].rewrite(reader);
}
return this;
}
@@ -86,8 +100,8 @@
/*(non-Javadoc) @see org.apache.lucene.search.Query#extractTerms(java.util.Set) */
public void extractTerms(Set terms) {
subQuery.extractTerms(terms);
- if (valSrcQuery!=null) {
- valSrcQuery.extractTerms(terms);
+ for(int i = 0; i < valSrcQueries.length; i++) {
+ valSrcQueries[i].extractTerms(terms);
}
}
@@ -95,8 +109,9 @@
public Object clone() {
CustomScoreQuery clone = (CustomScoreQuery)super.clone();
clone.subQuery = (Query) subQuery.clone();
- if (valSrcQuery!=null) {
- clone.valSrcQuery = (ValueSourceQuery) valSrcQuery.clone();
+ clone.valSrcQueries = new ValueSourceQuery[valSrcQueries.length];
+ for(int i = 0; i < valSrcQueries.length; i++) {
+ clone.valSrcQueries[i] = (ValueSourceQuery) valSrcQueries[i].clone();
}
return clone;
}
@@ -105,8 +120,8 @@
public String toString(String field) {
StringBuffer sb = new StringBuffer(name()).append("(");
sb.append(subQuery.toString(field));
- if (valSrcQuery!=null) {
- sb.append(", ").append(valSrcQuery.toString(field));
+ for(int i = 0; i < valSrcQueries.length; i++) {
+ sb.append(", ").append(valSrcQueries[i].toString(field));
}
sb.append(")");
sb.append(strict?" STRICT" : "");
@@ -119,26 +134,78 @@
return false;
}
CustomScoreQuery other = (CustomScoreQuery)o;
- return this.getBoost() == other.getBoost()
- && this.subQuery.equals(other.subQuery)
- && (this.valSrcQuery==null ? other.valSrcQuery==null
- : this.valSrcQuery.equals(other.valSrcQuery));
+ if (this.getBoost() != other.getBoost() ||
+ !this.subQuery.equals(other.subQuery)||
+ this.valSrcQueries.length != other.valSrcQueries.length) {
+ return false;
+ }
+ for (int i=0; i<valSrcQueries.length; i++) { //TODO simplify with Arrays.deepEquals() once moving to Java 1.5
+ if (!valSrcQueries[i].equals(other.valSrcQueries[i])) {
+ return false;
+ }
+ }
+ return true;
}
/** Returns a hash code value for this object. */
public int hashCode() {
- int valSrcHash = valSrcQuery==null ? 0 : valSrcQuery.hashCode();
+ int valSrcHash = 0;
+ for (int i=0; i<valSrcQueries.length; i++) { //TODO simplify with Arrays.deepHashcode() once moving to Java 1.5
+ valSrcHash += valSrcQueries[i].hashCode();
+ }
return (getClass().hashCode() + subQuery.hashCode() + valSrcHash) ^ Float.floatToIntBits(getBoost());
}
/**
+ * Compute a custom score by the subQuery score and a number of
+ * ValueSourceQuery scores.
+ * <p>
+ * Subclasses can override this method to modify the custom score.
+ * <p>
+ * If your custom scoring is different than the default herein you
+ * should override at least one of the two customScore() methods.
+ * If the number of ValueSourceQueries is always < 2 it is
+ * sufficient to override the other
+ * {@link #customScore(int, float, float) costomScore()}
+ * method, which is simpler.
+ * <p>
+ * The default computation herein is:
+ * <pre>
+ * ModifiedScore = valSrcScore * subQueryScore[0] * subQueryScore[1] * ...
+ * </pre>
+ *
+ * @param doc id of scored doc.
+ * @param subQueryScore score of that doc by the subQuery.
+ * @param valSrcScores score of that doc by the ValueSourceQuery.
+ * @return custom score.
+ */
+ public float customScore(int doc, float subQueryScore, float valSrcScores[]) {
+ if(valSrcScores.length == 1) {
+ return customScore(doc, subQueryScore, valSrcScores[0]);
+ }
+ if (valSrcScores.length == 0) {
+ return customScore(doc, subQueryScore, 1);
+ }
+ float score = subQueryScore;
+ for(int i = 0; i < valSrcScores.length; i++) {
+ score *= valSrcScores[i];
+ }
+ return score;
+ }
+
+ /**
* Compute a custom score by the subQuery score and the ValueSourceQuery score.
* <p>
* Subclasses can override this method to modify the custom score.
* <p>
+ * If your custom scoring is different than the default herein you
+ * should override at least one of the two customScore() methods.
+ * If the number of ValueSourceQueries is always < 2 it is
+ * sufficient to override this costomScore() method, which is simpler.
+ * <p>
* The default computation herein is:
* <pre>
- * ModifiedScore = valSrcScore * subQueryScore.
+ * ModifiedScore = valSrcScore * subQueryScore
* </pre>
*
* @param doc id of scored doc.
@@ -147,41 +214,76 @@
* @return custom score.
*/
public float customScore(int doc, float subQueryScore, float valSrcScore) {
- return valSrcScore * subQueryScore;
+ return subQueryScore * valSrcScore;
+ }
+
+ /**
+ * Explain the custom score.
+ * Whenever overriding {@link #customScore(int, float, float[])},
+ * this method should also be overridden to provide the correct explanation
+ * for the part of the custom scoring.
+ *
+ * @param doc doc being explained.
+ * @param subQueryExpl explanation for the sub-query part.
+ * @param valSrcExpls explanation for the value source part.
+ * @return an explanation for the custom score
+ */
+ public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpls[]) {
+ if(valSrcExpls.length == 1) {
+ return customExplain(doc, subQueryExpl, valSrcExpls[0]);
+ }
+ if (valSrcExpls.length == 0) {
+ return subQueryExpl;
+ }
+ float valSrcScore = 1;
+ for(int i = 0; i < valSrcExpls.length; i++) {
+ valSrcScore *= valSrcExpls[i].getValue();
+ }
+ Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:");
+ exp.addDetail(subQueryExpl);
+ for(int i = 0; i < valSrcExpls.length; i++) {
+ exp.addDetail(valSrcExpls[i]);
+ }
+ return exp;
}
/**
* Explain the custom score.
* Whenever overriding {@link #customScore(int, float, float)},
- * this method should also be overriden to provide the correct explanation
- * for the part of the custom scoring.
+ * this method should also be overridden to provide the correct explanation
+ * for the part of the custom scoring.
+ *
* @param doc doc being explained.
* @param subQueryExpl explanation for the sub-query part.
* @param valSrcExpl explanation for the value source part.
* @return an explanation for the custom score
*/
public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
- float valSrcScore = valSrcExpl==null ? 1 : valSrcExpl.getValue();
- Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:");
- exp.addDetail(subQueryExpl);
+ float valSrcScore = 1;
if (valSrcExpl != null) {
- exp.addDetail(valSrcExpl);
+ valSrcScore *= valSrcExpl.getValue();
}
+ Explanation exp = new Explanation( valSrcScore * subQueryExpl.getValue(), "custom score: product of:");
+ exp.addDetail(subQueryExpl);
+ exp.addDetail(valSrcExpl);
return exp;
}
+
//=========================== W E I G H T ============================
private class CustomWeight implements Weight {
Similarity similarity;
Weight subQueryWeight;
- Weight valSrcWeight; // optional
+ Weight[] valSrcWeights;
boolean qStrict;
public CustomWeight(Searcher searcher) throws IOException {
this.similarity = getSimilarity(searcher);
this.subQueryWeight = subQuery.weight(searcher);
- if (valSrcQuery!=null) {
- this.valSrcWeight = valSrcQuery.createWeight(searcher);
+ this.subQueryWeight = subQuery.weight(searcher);
+ this.valSrcWeights = new Weight[valSrcQueries.length];
+ for(int i = 0; i < valSrcQueries.length; i++) {
+ this.valSrcWeights[i] = valSrcQueries[i].createWeight(searcher);
}
this.qStrict = strict;
}
@@ -199,11 +301,11 @@
/*(non-Javadoc) @see org.apache.lucene.search.Weight#sumOfSquaredWeights() */
public float sumOfSquaredWeights() throws IOException {
float sum = subQueryWeight.sumOfSquaredWeights();
- if (valSrcWeight!=null) {
+ for(int i = 0; i < valSrcWeights.length; i++) {
if (qStrict) {
- valSrcWeight.sumOfSquaredWeights(); // do not include ValueSource part in the query normalization
+ valSrcWeights[i].sumOfSquaredWeights(); // do not include ValueSource part in the query normalization
} else {
- sum += valSrcWeight.sumOfSquaredWeights();
+ sum += valSrcWeights[i].sumOfSquaredWeights();
}
}
sum *= getBoost() * getBoost(); // boost each sub-weight
@@ -214,11 +316,11 @@
public void normalize(float norm) {
norm *= getBoost(); // incorporate boost
subQueryWeight.normalize(norm);
- if (valSrcWeight!=null) {
+ for(int i = 0; i < valSrcWeights.length; i++) {
if (qStrict) {
- valSrcWeight.normalize(1); // do not normalize the ValueSource part
+ valSrcWeights[i].normalize(1); // do not normalize the ValueSource part
} else {
- valSrcWeight.normalize(norm);
+ valSrcWeights[i].normalize(norm);
}
}
}
@@ -226,8 +328,11 @@
/*(non-Javadoc) @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader) */
public Scorer scorer(IndexReader reader) throws IOException {
Scorer subQueryScorer = subQueryWeight.scorer(reader);
- Scorer valSrcScorer = (valSrcWeight==null ? null : valSrcWeight.scorer(reader));
- return new CustomScorer(similarity, reader, this, subQueryScorer, valSrcScorer);
+ Scorer[] valSrcScorers = new Scorer[valSrcWeights.length];
+ for(int i = 0; i < valSrcScorers.length; i++) {
+ valSrcScorers[i] = valSrcWeights[i].scorer(reader);
+ }
+ return new CustomScorer(similarity, reader, this, subQueryScorer, valSrcScorers);
}
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
@@ -246,25 +351,29 @@
private final CustomWeight weight;
private final float qWeight;
private Scorer subQueryScorer;
- private Scorer valSrcScorer; // optional
+ private Scorer[] valSrcScorers;
private IndexReader reader;
+ private float vScores[]; // reused in score() to avoid allocating this array for each doc
// constructor
private CustomScorer(Similarity similarity, IndexReader reader, CustomWeight w,
- Scorer subQueryScorer, Scorer valSrcScorer) throws IOException {
+ Scorer subQueryScorer, Scorer[] valSrcScorers) throws IOException {
super(similarity);
this.weight = w;
this.qWeight = w.getValue();
this.subQueryScorer = subQueryScorer;
- this.valSrcScorer = valSrcScorer;
+ this.valSrcScorers = valSrcScorers;
this.reader = reader;
+ this.vScores = new float[valSrcScorers.length];
}
/*(non-Javadoc) @see org.apache.lucene.search.Scorer#next() */
public boolean next() throws IOException {
boolean hasNext = subQueryScorer.next();
- if (valSrcScorer!=null && hasNext) {
- valSrcScorer.skipTo(subQueryScorer.doc());
+ if(hasNext) {
+ for(int i = 0; i < valSrcScorers.length; i++) {
+ valSrcScorers[i].skipTo(subQueryScorer.doc());
+ }
}
return hasNext;
}
@@ -276,15 +385,19 @@
/*(non-Javadoc) @see org.apache.lucene.search.Scorer#score() */
public float score() throws IOException {
- float valSrcScore = (valSrcScorer==null ? 1 : valSrcScorer.score());
- return qWeight * customScore(subQueryScorer.doc(), subQueryScorer.score(), valSrcScore);
+ for(int i = 0; i < valSrcScorers.length; i++) {
+ vScores[i] = valSrcScorers[i].score();
+ }
+ return qWeight * customScore(subQueryScorer.doc(), subQueryScorer.score(), vScores);
}
/*(non-Javadoc) @see org.apache.lucene.search.Scorer#skipTo(int) */
public boolean skipTo(int target) throws IOException {
boolean hasNext = subQueryScorer.skipTo(target);
- if (valSrcScorer!=null && hasNext) {
- valSrcScorer.skipTo(subQueryScorer.doc());
+ if(hasNext) {
+ for(int i = 0; i < valSrcScorers.length; i++) {
+ valSrcScorers[i].skipTo(subQueryScorer.doc());
+ }
}
return hasNext;
}
@@ -296,8 +409,11 @@
return subQueryExpl;
}
// match
- Explanation valSrcExpl = valSrcScorer==null ? null : valSrcScorer.explain(doc);
- Explanation customExp = customExplain(doc,subQueryExpl,valSrcExpl);
+ Explanation[] valSrcExpls = new Explanation[valSrcScorers.length];
+ for(int i = 0; i < valSrcScorers.length; i++) {
+ valSrcExpls[i] = valSrcScorers[i].explain(doc);
+ }
+ Explanation customExp = customExplain(doc,subQueryExpl,valSrcExpls);
float sc = qWeight * customExp.getValue();
Explanation res = new ComplexExplanation(
true, sc, CustomScoreQuery.this.toString() + ", product of:");
Modified: lucene/java/trunk/src/test/org/apache/lucene/search/function/FunctionTestSetup.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/function/FunctionTestSetup.java?rev=603837&r1=603836&r2=603837&view=diff
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/search/function/FunctionTestSetup.java (original)
+++ lucene/java/trunk/src/test/org/apache/lucene/search/function/FunctionTestSetup.java Wed Dec 12 22:28:27 2007
@@ -37,7 +37,7 @@
* Actual score computation order is slightly different than assumptios
* this allows for a small amount of variation
*/
- public static float TEST_SCORE_TOLERANCE_DELTA = 0.00005f;
+ public static float TEST_SCORE_TOLERANCE_DELTA = 0.001f;
protected static final boolean DBG = false; // change to true for logging to print
Modified: lucene/java/trunk/src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java?rev=603837&r1=603836&r2=603837&view=diff
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java (original)
+++ lucene/java/trunk/src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java Wed Dec 12 22:28:27 2007
@@ -80,13 +80,78 @@
doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,6.0);
}
+ // must have static class otherwise serialization tests fail
+ private static class CustomAddQuery extends CustomScoreQuery {
+ // constructor
+ CustomAddQuery (Query q, ValueSourceQuery qValSrc) {
+ super(q,qValSrc);
+ }
+ /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
+ public String name() {
+ return "customAdd";
+ }
+ /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
+ public float customScore(int doc, float subQueryScore, float valSrcScore) {
+ return subQueryScore + valSrcScore;
+ }
+ /* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
+ public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
+ float valSrcScore = valSrcExpl==null ? 0 : valSrcExpl.getValue();
+ Explanation exp = new Explanation( valSrcScore + subQueryExpl.getValue(), "custom score: sum of:");
+ exp.addDetail(subQueryExpl);
+ if (valSrcExpl != null) {
+ exp.addDetail(valSrcExpl);
+ }
+ return exp;
+ }
+ }
+
+ // must have static class otherwise serialization tests fail
+ private static class CustomMulAddQuery extends CustomScoreQuery {
+ // constructor
+ CustomMulAddQuery(Query q, ValueSourceQuery qValSrc1, ValueSourceQuery qValSrc2) {
+ super(q,new ValueSourceQuery[]{qValSrc1,qValSrc2});
+ }
+ /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
+ public String name() {
+ return "customMulAdd";
+ }
+ /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
+ public float customScore(int doc, float subQueryScore, float valSrcScores[]) {
+ if (valSrcScores.length == 0) {
+ return subQueryScore;
+ }
+ if (valSrcScores.length == 1) {
+ return subQueryScore + valSrcScores[0];
+ }
+ return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two
+ }
+ /* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
+ public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpls[]) {
+ if (valSrcExpls.length == 0) {
+ return subQueryExpl;
+ }
+ Explanation exp = new Explanation(valSrcExpls[0].getValue() + subQueryExpl.getValue(), "sum of:");
+ exp.addDetail(subQueryExpl);
+ exp.addDetail(valSrcExpls[0]);
+ if (valSrcExpls.length == 1) {
+ exp.setDescription("CustomMulAdd, sum of:");
+ return exp;
+ }
+ Explanation exp2 = new Explanation(valSrcExpls[1].getValue() * exp.getValue(), "custom score: product of:");
+ exp2.addDetail(valSrcExpls[1]);
+ exp2.addDetail(exp);
+ return exp2;
+ }
+ }
+
// Test that FieldScoreQuery returns docs with expected score.
private void doTestCustomScore (String field, FieldScoreQuery.Type tp, double dboost) throws CorruptIndexException, Exception {
float boost = (float) dboost;
IndexSearcher s = new IndexSearcher(dir);
FieldScoreQuery qValSrc = new FieldScoreQuery(field,tp); // a query that would score by the field
QueryParser qp = new QueryParser(TEXT_FIELD,anlzr);
- String qtxt = "bleeding person chain knowledge"; // from the doc texts in FunctionQuerySetup.
+ String qtxt = "first aid text"; // from the doc texts in FunctionQuerySetup.
// regular (boolean) query.
Query q1 = qp.parse(qtxt);
@@ -104,55 +169,13 @@
log(q3CustomMul);
// custom query, that should add the scores of q1 to that of the field
- CustomScoreQuery q4CustomAdd = new CustomScoreQuery(q1,qValSrc) {
- /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
- public String name() {
- return "customAdd";
- }
- /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
- public float customScore(int doc, float subQueryScore, float valSrcScore) {
- return subQueryScore + valSrcScore;
- }
- /* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
- public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
- float valSrcScore = valSrcExpl==null ? 0 : valSrcExpl.getValue();
- Explanation exp = new Explanation( valSrcScore + subQueryExpl.getValue(), "custom score: sum of:");
- exp.addDetail(subQueryExpl);
- if (valSrcExpl != null) {
- exp.addDetail(valSrcExpl);
- }
- return exp;
- }
- };
+ CustomScoreQuery q4CustomAdd = new CustomAddQuery(q1,qValSrc);
q4CustomAdd.setStrict(true);
q4CustomAdd.setBoost(boost);
log(q4CustomAdd);
// custom query, that multiplies and adds the field score to that of q1
- CustomScoreQuery q5CustomMulAdd = new CustomScoreQuery(q1,qValSrc) {
- /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
- public String name() {
- return "customMulAdd";
- }
- /*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
- public float customScore(int doc, float subQueryScore, float valSrcScore) {
- return (1 + subQueryScore) * valSrcScore;
- }
- /* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
- public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
- Explanation exp = new Explanation(1 + subQueryExpl.getValue(), "sum of:");
- exp.addDetail(subQueryExpl);
- exp.addDetail(new Explanation(1,"const 1"));
- if (valSrcExpl == null) {
- exp.setDescription("CustomMulAdd, sum of:");
- return exp;
- }
- Explanation exp2 = new Explanation(valSrcExpl.getValue() * exp.getValue(), "custom score: product of:");
- exp2.addDetail(valSrcExpl);
- exp2.addDetail(exp);
- return exp2;
- }
- };
+ CustomScoreQuery q5CustomMulAdd = new CustomMulAddQuery(q1,qValSrc,qValSrc);
q5CustomMulAdd.setStrict(true);
q5CustomMulAdd.setBoost(boost);
log(q5CustomMulAdd);
@@ -216,7 +239,7 @@
float score5 = ((Float)h5CustomMulAdd.get(x)).floatValue();
logResult("score5=", s, q5, doc, score5);
- assertEquals("new score for custom mul add", boost * fieldScore * (score1 + 1), score5, TEST_SCORE_TOLERANCE_DELTA);
+ assertEquals("new score for custom mul add", boost * fieldScore * (score1 + fieldScore), score5, TEST_SCORE_TOLERANCE_DELTA);
}
}