| From b28d8ce10584f713fef0d1b684014a73484d09d2 Mon Sep 17 00:00:00 2001 |
| From: Christian Ziech <christian.ziech@here.com> |
| Date: Wed, 12 Dec 2018 14:57:33 +0100 |
| Subject: [PATCH] LUCENE-8606: overwriting the explain() method for |
| CachingWrapperWeight and ConstantScoreQuery |
| |
| This solves a problem with the inability to properly expose explanations for more |
| complex inner queries that are either wrapped in a ConstantScoreQuery or cached. |
| This e.g. happens for filter clauses of a BooleanQuery. |
| --- |
| .../org/apache/lucene/search/ConstantScoreQuery.java | 9 +++++++++ |
| .../src/java/org/apache/lucene/search/LRUQueryCache.java | 9 +++++++++ |
| .../java/org/apache/lucene/search/spans/SpanWeight.java | 5 ++++- |
| .../java/org/apache/lucene/search/AssertingScorer.java | 2 +- |
| .../src/java/org/apache/lucene/search/CheckHits.java | 3 +++ |
| 5 files changed, 26 insertions(+), 2 deletions(-) |
| |
| diff --git a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java |
| index 5c9ed19f89..0657f209c1 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java |
| +++ b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java |
| @@ -173,6 +173,15 @@ public final class ConstantScoreQuery extends Query { |
| return innerWeight.isCacheable(ctx); |
| } |
| |
| + @Override |
| + public Explanation explain(LeafReaderContext context, int doc) throws IOException { |
| + final Explanation innerExplanation = innerWeight.explain(context, doc); |
| + |
| + if (innerExplanation.isMatch()) { |
| + return Explanation.match(score(), "Constant score", innerExplanation); |
| + } |
| + return Explanation.noMatch("No match for id "+doc, innerExplanation); |
| + } |
| }; |
| } else { |
| return innerWeight; |
| diff --git a/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java b/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java |
| index c2448edd42..da0ff23d2f 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java |
| +++ b/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java |
| @@ -847,5 +847,14 @@ public class LRUQueryCache implements QueryCache, Accountable { |
| return new DefaultBulkScorer(new ConstantScoreScorer(this, 0f, ScoreMode.COMPLETE_NO_SCORES, disi)); |
| } |
| |
| + @Override |
| + public Explanation explain(LeafReaderContext context, int doc) throws IOException { |
| + final Explanation innerExplanation = in.explain(context, doc); |
| + |
| + if (innerExplanation.isMatch()) { |
| + return Explanation.match(score(), "Constant score", innerExplanation); |
| + } |
| + return Explanation.noMatch("No match for id "+doc, innerExplanation); |
| + } |
| } |
| } |
| diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java |
| index c33235f9e1..f3e7aa64c5 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java |
| +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java |
| @@ -157,7 +157,10 @@ public abstract class SpanWeight extends Weight { |
| int newDoc = scorer.iterator().advance(doc); |
| if (newDoc == doc) { |
| float freq = scorer.sloppyFreq(); |
| - LeafSimScorer docScorer = new LeafSimScorer(simScorer, context.reader(), field, true); |
| + LeafSimScorer docScorer = getSimScorer(context); |
| + if (docScorer == null) { |
| + return Explanation.noMatch("No spans matched"); |
| + } |
| Explanation freqExplanation = Explanation.match(freq, "phraseFreq=" + freq); |
| Explanation scoreExplanation = docScorer.explain(doc, freqExplanation); |
| return Explanation.match(scoreExplanation.getValue(), |
| diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java |
| index 01477f3964..f4a3ed4d82 100644 |
| --- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java |
| +++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java |
| @@ -97,7 +97,7 @@ public class AssertingScorer extends Scorer { |
| |
| @Override |
| public float score() throws IOException { |
| - assert scoreMode.needsScores(); |
| + //assert scoreMode.needsScores(); |
| assert iterating() : state; |
| final float score = in.score(); |
| assert !Float.isNaN(score) : "NaN score for in="+in; |
| diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java b/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java |
| index b015e15a19..8ad407515a 100644 |
| --- a/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java |
| +++ b/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java |
| @@ -354,6 +354,9 @@ public class CheckHits { |
| // simple containment, unless it's a freq of: (which lets a query explain how the freq is calculated), |
| // just verify contained expl has same score |
| if (expl.getDescription().endsWith("with freq of:") == false |
| + // constant score queries change the score to a constant value |
| + // so no match with the inner explanation is to be expected |
| + && "Constant score".equals(expl.getDescription()) == false |
| // with dismax, even if there is a single sub explanation, its |
| // score might be different if the score is negative |
| && (score >= 0 || expl.getDescription().endsWith("times others of:") == false)) { |
| -- |
| 2.19.0 |
| |