You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2013/04/17 16:58:30 UTC
svn commit: r1468952 - in /lucene/dev/trunk/lucene: CHANGES.txt
queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java
queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java
Author: rmuir
Date: Wed Apr 17 14:58:30 2013
New Revision: 1468952
URL: http://svn.apache.org/r1468952
Log:
LUCENE-4935: CustomScoreQuery has broken boosting
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java
lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1468952&r1=1468951&r2=1468952&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed Apr 17 14:58:30 2013
@@ -35,6 +35,13 @@ Optimizations
on Windows if NIOFSDirectory is used, mmapped files are still locked.
(Michael Poindexter, Robert Muir, Uwe Schindler)
+======================= Lucene 4.4.0 =======================
+
+Bug Fixes
+
+* LUCENE-4935: CustomScoreQuery wrongly applied its query boost twice
+ (boost^2). (Robert Muir)
+
======================= Lucene 4.3.0 =======================
Changes in backwards compatibility policy
Modified: lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java?rev=1468952&r1=1468951&r2=1468952&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java (original)
+++ lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java Wed Apr 17 14:58:30 2013
@@ -184,6 +184,7 @@ public class CustomScoreQuery extends Qu
Weight subQueryWeight;
Weight[] valSrcWeights;
boolean qStrict;
+ float queryWeight;
public CustomWeight(IndexSearcher searcher) throws IOException {
this.subQueryWeight = subQuery.createWeight(searcher);
@@ -210,22 +211,26 @@ public class CustomScoreQuery extends Qu
sum += valSrcWeight.getValueForNormalization();
}
}
- sum *= getBoost() * getBoost(); // boost each sub-weight
- return sum ;
+ return sum;
}
/*(non-Javadoc) @see org.apache.lucene.search.Weight#normalize(float) */
@Override
public void normalize(float norm, float topLevelBoost) {
- topLevelBoost *= getBoost(); // incorporate boost
- subQueryWeight.normalize(norm, topLevelBoost);
+ // note we DONT incorporate our boost, nor pass down any topLevelBoost
+ // (e.g. from outer BQ), as there is no guarantee that the CustomScoreProvider's
+ // function obeys the distributive law... it might call sqrt() on the subQuery score
+ // or some other arbitrary function other than multiplication.
+ // so, instead boosts are applied directly in score()
+ subQueryWeight.normalize(norm, 1f);
for (Weight valSrcWeight : valSrcWeights) {
if (qStrict) {
valSrcWeight.normalize(1, 1); // do not normalize the ValueSource part
} else {
- valSrcWeight.normalize(norm, topLevelBoost);
+ valSrcWeight.normalize(norm, 1f);
}
}
+ queryWeight = topLevelBoost * getBoost();
}
@Override
@@ -244,7 +249,7 @@ public class CustomScoreQuery extends Qu
for(int i = 0; i < valSrcScorers.length; i++) {
valSrcScorers[i] = valSrcWeights[i].scorer(context, true, topScorer, acceptDocs);
}
- return new CustomScorer(CustomScoreQuery.this.getCustomScoreProvider(context), this, getBoost(), subQueryScorer, valSrcScorers);
+ return new CustomScorer(CustomScoreQuery.this.getCustomScoreProvider(context), this, queryWeight, subQueryScorer, valSrcScorers);
}
@Override
Modified: lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java?rev=1468952&r1=1468951&r2=1468952&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java (original)
+++ lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java Wed Apr 17 14:58:30 2013
@@ -46,8 +46,6 @@ import org.apache.lucene.index.Term;
*/
public class TestCustomScoreQuery extends FunctionTestSetup {
- // TODO: why can't this test use newSearcher?
-
@BeforeClass
public static void beforeClass() throws Exception {
createIndex(true);
@@ -211,7 +209,7 @@ public class TestCustomScoreQuery extend
log(q);
IndexReader r = DirectoryReader.open(dir);
- IndexSearcher s = new IndexSearcher(r);
+ IndexSearcher s = newSearcher(r);
TopDocs hits = s.search(q, 1000);
assertEquals(N_DOCS, hits.totalHits);
for(int i=0;i<N_DOCS;i++) {
@@ -225,7 +223,7 @@ public class TestCustomScoreQuery extend
@Test
public void testRewrite() throws Exception {
IndexReader r = DirectoryReader.open(dir);
- final IndexSearcher s = new IndexSearcher(r);
+ final IndexSearcher s = newSearcher(r);
Query q = new TermQuery(new Term(TEXT_FIELD, "first"));
CustomScoreQuery original = new CustomScoreQuery(q);
@@ -250,7 +248,7 @@ public class TestCustomScoreQuery extend
float boost = (float) dboost;
FunctionQuery functionQuery = new FunctionQuery(valueSource);
IndexReader r = DirectoryReader.open(dir);
- IndexSearcher s = new IndexSearcher(r);
+ IndexSearcher s = newSearcher(r);
// regular (boolean) query.
BooleanQuery q1 = new BooleanQuery();
@@ -260,8 +258,13 @@ public class TestCustomScoreQuery extend
log(q1);
// custom query, that should score the same as q1.
- Query q2CustomNeutral = new CustomScoreQuery(q1);
- q2CustomNeutral.setBoost(boost);
+ BooleanQuery q2CustomNeutral = new BooleanQuery(true);
+ Query q2CustomNeutralInner = new CustomScoreQuery(q1);
+ q2CustomNeutral.add(q2CustomNeutralInner, BooleanClause.Occur.SHOULD);
+ // a little tricky: we split the boost across an outer BQ and CustomScoreQuery
+ // this ensures boosting is correct across all these functions (see LUCENE-4935)
+ q2CustomNeutral.setBoost((float)Math.sqrt(dboost));
+ q2CustomNeutralInner.setBoost((float)Math.sqrt(dboost));
log(q2CustomNeutral);
// custom query, that should (by default) multiply the scores of q1 by that of the field