@Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { Scorer scorer = scorer(context, true, false, context.reader().getLiveDocs()); if (scorer != null) { int newDoc = scorer.advance(doc); if (newDoc == doc) { float freq = scorer.freq(); SloppySimScorer docScorer = similarity.sloppySimScorer(stats, context); ComplexExplanation result = new ComplexExplanation(); result.setDescription( "weight(" + getQuery() + " in " + doc + ") [" + similarity.getClass().getSimpleName() + "], result of:"); Explanation scoreExplanation = docScorer.explain(doc, new Explanation(freq, "phraseFreq=" + freq)); result.addDetail(scoreExplanation); result.setValue(scoreExplanation.getValue()); result.setMatch(true); return result; } } return new ComplexExplanation(false, 0.0f, "no matching term"); }
@Override public Explanation explain(LeafReaderContext context, int doc) throws IOException { final Scorer s = scorer(context); final boolean exists; if (s == null) { exists = false; } else { final TwoPhaseIterator twoPhase = s.twoPhaseIterator(); if (twoPhase == null) { exists = s.iterator().advance(doc) == doc; } else { exists = twoPhase.approximation().advance(doc) == doc && twoPhase.matches(); } } if (exists) { return Explanation.match( queryWeight, getQuery().toString() + ", product of:", Explanation.match(boost, "boost"), Explanation.match(queryNorm, "queryNorm")); } else { return Explanation.noMatch(getQuery().toString() + " doesn't match id " + doc); } }
@Override public BranchingDecision getDecision(Decision decision, boolean isLeft) { BranchingDecision br = super.getDecision(decision, isLeft); if (!isLeft) { // a refutation is explained thanks to the previous ones which are refutable if (decision != RootDecision.ROOT) { Explanation explanation = database.get(br.getId()); if (explanation == null) { explanation = new Explanation(); } else { explanation.reset(); } Decision d = decision.getPrevious(); while ((d != RootDecision.ROOT)) { if (d.hasNext()) { explanation.add(d.getPositiveDeduction()); } d = d.getPrevious(); } this.store(br, explanation); } } return br; }
public Explanation explain(int doc) throws IOException { float sc = qWeight * vals.floatVal(doc); Explanation result = new ComplexExplanation(true, sc, "FunctionQuery(" + func + "), product of:"); result.addDetail(vals.explain(doc)); result.addDetail(new Explanation(getBoost(), "boost")); result.addDetail(new Explanation(weight.queryNorm, "queryNorm")); return result; }
public static Explanation readExplanation(StreamInput in) throws IOException { float value = in.readFloat(); String description = in.readString(); Explanation explanation = new Explanation(value, description); if (in.readBoolean()) { int size = in.readVInt(); for (int i = 0; i < size; i++) { explanation.addDetail(readExplanation(in)); } } return explanation; }
public static void writeExplanation(StreamOutput out, Explanation explanation) throws IOException { out.writeFloat(explanation.getValue()); out.writeString(explanation.getDescription()); Explanation[] subExplanations = explanation.getDetails(); if (subExplanations == null) { out.writeBoolean(false); } else { out.writeBoolean(true); out.writeVInt(subExplanations.length); for (Explanation subExp : subExplanations) { writeExplanation(out, subExp); } } }
/** Explain the score we computed for doc */ @Override public Explanation explain(LeafReaderContext context, int doc) throws IOException { if (disjuncts.size() == 1) return weights.get(0).explain(context, doc); ComplexExplanation result = new ComplexExplanation(); float max = 0.0f, sum = 0.0f; result.setDescription( tieBreakerMultiplier == 0.0f ? "max of:" : "max plus " + tieBreakerMultiplier + " times others of:"); for (Weight wt : weights) { Explanation e = wt.explain(context, doc); if (e.isMatch()) { result.setMatch(Boolean.TRUE); result.addDetail(e); sum += e.getValue(); max = Math.max(max, e.getValue()); } } result.setValue(max + (sum - max) * tieBreakerMultiplier); return result; }
/** Explain the score we computed for doc */ @Override public Explanation explain(LeafReaderContext context, int doc) throws IOException { boolean match = false; float max = 0.0f, sum = 0.0f; List<Explanation> subs = new ArrayList<>(); for (Weight wt : weights) { Explanation e = wt.explain(context, doc); if (e.isMatch()) { match = true; subs.add(e); sum += e.getValue(); max = Math.max(max, e.getValue()); } } if (match) { final float score = max + (sum - max) * tieBreakerMultiplier; final String desc = tieBreakerMultiplier == 0.0f ? "max of:" : "max plus " + tieBreakerMultiplier + " times others of:"; return Explanation.match(score, desc, subs); } else { return Explanation.noMatch("No matching clause"); } }
@Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { Scorer scorer = scorer(context, true, context.isTopLevel, context.reader().getLiveDocs()); scorer.advance(doc); float score = scorer.score(); Explanation expl = new Explanation(score, "name query score"); if (scorer instanceof DisjunctionTermMatchedScorer) { DisjunctionTermMatchedScorer distScorer = (DisjunctionTermMatchedScorer) scorer; float numUniques = distScorer.getNumUniqTerms(doc); expl.addDetail(new Explanation(numUniques, "number of unique terms")); expl.addDetail(new Explanation(distScorer.nrMatchers, "number of terms matched")); expl.addDetail(new Explanation(distScorer.numTerms, "number of query terms")); float matchRatio = distScorer.calculateMatchedRatio(numUniques); expl.addDetail(new Explanation(matchRatio, "match ratio")); } return expl; }
@Override public void explain(ExplanationEngine xengine, Deduction d, Explanation e) { // return super.explain(d); if (d.getVar() == x) { e.add(xengine.getPropagatorActivation(this)); if (d.getmType() == Deduction.Type.ValRem) { y.explain(xengine, VariableState.REM, ((ValueRemoval) d).getVal() - cste, e); } else { throw new UnsupportedOperationException( "PropEqualXY only knows how to explain ValueRemovals"); } } else if (d.getVar() == y) { e.add(xengine.getPropagatorActivation(this)); if (d.getmType() == Deduction.Type.ValRem) { x.explain(xengine, VariableState.REM, ((ValueRemoval) d).getVal() + cste, e); } else { throw new UnsupportedOperationException( "PropEqualXY only knows how to explain ValueRemovals"); } } else { super.explain(xengine, d, e); } }
public Explanation explain(int doc) throws IOException { Explanation subQueryExpl = weight.qWeight.explain(reader, doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; } float sc = subQueryExpl.getValue() * vals.floatVal(doc); Explanation res = new ComplexExplanation(true, sc, BoostedQuery.this.toString() + ", product of:"); res.addDetail(subQueryExpl); res.addDetail(vals.explain(doc)); return res; }
@Override public Explanation explain(IndexReader reader, int doc) throws IOException { SolrIndexReader topReader = (SolrIndexReader) reader; SolrIndexReader[] subReaders = topReader.getLeafReaders(); int[] offsets = topReader.getLeafOffsets(); int readerPos = SolrIndexReader.readerIndex(doc, offsets); int readerBase = offsets[readerPos]; Explanation subQueryExpl = qWeight.explain(reader, doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; } DocValues vals = boostVal.getValues(context, subReaders[readerPos]); float sc = subQueryExpl.getValue() * vals.floatVal(doc - readerBase); Explanation res = new ComplexExplanation(true, sc, BoostedQuery.this.toString() + ", product of:"); res.addDetail(subQueryExpl); res.addDetail(vals.explain(doc - readerBase)); return res; }
@Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { ComplexExplanation result = new ComplexExplanation(); result.setDescription("weight(" + getQuery() + " in " + doc + "), product of:"); Explanation idfExpl = new Explanation(idf, "idf(" + field + ":" + idfExp.explain() + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.setDescription("queryWeight(" + getQuery() + "), product of:"); Explanation boostExpl = new Explanation(getBoost(), "boost"); if (getBoost() != 1.0f) queryExpl.addDetail(boostExpl); queryExpl.addDetail(idfExpl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.addDetail(queryNormExpl); queryExpl.setValue(boostExpl.getValue() * idfExpl.getValue() * queryNormExpl.getValue()); result.addDetail(queryExpl); // explain field weight ComplexExplanation fieldExpl = new ComplexExplanation(); fieldExpl.setDescription("fieldWeight(" + getQuery() + " in " + doc + "), product of:"); Scorer scorer = scorer(context, ScorerContext.def()); if (scorer == null) { return new Explanation(0.0f, "no matching docs"); } Explanation tfExplanation = new Explanation(); int d = scorer.advance(doc); float phraseFreq; if (d == doc) { phraseFreq = scorer.freq(); } else { phraseFreq = 0.0f; } tfExplanation.setValue(similarity.tf(phraseFreq)); tfExplanation.setDescription("tf(phraseFreq=" + phraseFreq + ")"); fieldExpl.addDetail(tfExplanation); fieldExpl.addDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = context.reader.norms(field); float fieldNorm = fieldNorms != null ? similarity.decodeNormValue(fieldNorms[doc]) : 1.0f; fieldNormExpl.setValue(fieldNorm); fieldNormExpl.setDescription("fieldNorm(field=" + field + ", doc=" + doc + ")"); fieldExpl.addDetail(fieldNormExpl); fieldExpl.setMatch(Boolean.valueOf(tfExplanation.isMatch())); fieldExpl.setValue(tfExplanation.getValue() * idfExpl.getValue() * fieldNormExpl.getValue()); result.addDetail(fieldExpl); result.setMatch(fieldExpl.getMatch()); // combine them result.setValue(queryExpl.getValue() * fieldExpl.getValue()); if (queryExpl.getValue() == 1.0f) return fieldExpl; return result; }
public Explanation explain(IndexReader reader, int doc) throws IOException { ComplexExplanation result = new ComplexExplanation(); result.setDescription("weight(" + getQuery() + " in " + doc + "), product of:"); Explanation idfExpl = new Explanation(idf, "idf(docFreq=" + reader.docFreq(term) + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.setDescription("queryWeight(" + getQuery() + "), product of:"); Explanation boostExpl = new Explanation(getBoost(), "boost"); if (getBoost() != 1.0f) queryExpl.addDetail(boostExpl); queryExpl.addDetail(idfExpl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.addDetail(queryNormExpl); queryExpl.setValue(boostExpl.getValue() * idfExpl.getValue() * queryNormExpl.getValue()); result.addDetail(queryExpl); // explain field weight String field = term.field(); ComplexExplanation fieldExpl = new ComplexExplanation(); fieldExpl.setDescription("fieldWeight(" + term + " in " + doc + "), product of:"); Explanation tfExpl = scorer(reader).explain(doc); fieldExpl.addDetail(tfExpl); fieldExpl.addDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.norms(field); float fieldNorm = fieldNorms != null ? Similarity.decodeNorm(fieldNorms[doc]) : 0.0f; fieldNormExpl.setValue(fieldNorm); fieldNormExpl.setDescription("fieldNorm(field=" + field + ", doc=" + doc + ")"); fieldExpl.addDetail(fieldNormExpl); fieldExpl.setMatch(Boolean.valueOf(tfExpl.isMatch())); fieldExpl.setValue(tfExpl.getValue() * idfExpl.getValue() * fieldNormExpl.getValue()); result.addDetail(fieldExpl); result.setMatch(fieldExpl.getMatch()); // combine them result.setValue(queryExpl.getValue() * fieldExpl.getValue()); if (queryExpl.getValue() == 1.0f) return fieldExpl; return result; }