public virtual Explanation Explain(IndexReader indexReader, int docid, Explanation innerExplaination) { if (!(indexReader is BoboIndexReader)) throw new ArgumentException("IndexReader is not BoboIndexReader"); BoboIndexReader reader = (BoboIndexReader)indexReader; Explanation exp = new Explanation(); exp.Description = "FacetBasedBoost"; float boost = 1.0f; foreach (var boostEntry in _boostMaps) { string facetName = boostEntry.Key; IFacetHandler handler = reader.GetFacetHandler(facetName); if (!(handler is IFacetScoreable)) throw new ArgumentException(facetName + " does not implement IFacetScoreable"); IFacetScoreable facetScoreable = (IFacetScoreable)handler; BoboDocScorer scorer = facetScoreable.GetDocScorer(reader, _scoringFunctionFactory, boostEntry.Value); float facetBoost = scorer.Score(docid); Explanation facetExp = new Explanation(); facetExp.Description = facetName; facetExp.Value = facetBoost; facetExp.AddDetail(scorer.Explain(docid)); boost *= facetBoost; exp.AddDetail(facetExp); } exp.Value = boost; exp.AddDetail(innerExplaination); return exp; }
public override Explanation Explain(int doc) { Explanation explanation = new Explanation(); explanation.SetValue(1.0f); explanation.SetDescription("MatchAllDocsQuery"); return explanation; }
public virtual Explanation Explain(int df, float boost) { Explanation expl = new Explanation(); expl.Value = Score(df, boost); expl.Description = "facet boost value of: " + boost; return expl; }
public virtual Explanation Explain(IndexReader reader, int doc, Explanation innerExplanation) { if (reader is BoboIndexReader) { BoboIndexReader boboReader = (BoboIndexReader)reader; object dataObj = boboReader.GetFacetData(_timeFacetName); if (dataObj is FacetDataCache) { FacetDataCache facetDataCache = (FacetDataCache)(boboReader.GetFacetData(_timeFacetName)); BigSegmentedArray orderArray = facetDataCache.OrderArray; TermLongList termList = (TermLongList)facetDataCache.ValArray; long now = System.Environment.TickCount; Explanation finalExpl = new Explanation(); finalExpl.AddDetail(innerExplanation); float rawScore = innerExplanation.Value; long timeVal = termList.GetPrimitiveValue(orderArray.Get(doc)); float timeScore = ComputeTimeFactor(timeVal); float finalScore = CombineScores(timeScore, rawScore); finalExpl.Value = finalScore; finalExpl.Description = "final score = (time score: " + timeScore + ") * (raw score: " + rawScore + "), timeVal: " + timeVal; return finalExpl; } else { throw new InvalidOperationException("underlying facet data must be of type FacetDataCache<long>"); } } else { throw new ArgumentException("reader not instance of " + typeof(BoboIndexReader)); } }
/// <summary>Explain the score of a document.</summary> /// <todo> Also show the total score. </todo> /// <summary> See BooleanScorer.explain() on how to do this. /// </summary> public override Explanation Explain(int doc) { Explanation res = new Explanation(); res.SetDescription("required, optional"); res.AddDetail(reqScorer.Explain(doc)); res.AddDetail(optScorer.Explain(doc)); return res; }
public override Explanation Explain(IndexReader reader, int doc) { Explanation result = new Explanation(); result.Value = _weight; result.Description = _parent.ToString(); return result; }
public virtual Explanation Explain(params float[] scores) { float sum = 0.0f; foreach (float score in scores) { sum += score; } Explanation expl = new Explanation(sum, "sum of: " + Arrays.ToString(scores)); return expl; }
public override Explanation Explain(IndexReader reader, int doc) { ComplexExplanation result = new ComplexExplanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); System.String field = ((SpanQuery) GetQuery()).GetField(); 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(GetQuery().GetBoost(), "boost"); if (GetQuery().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(" + field + ":" + query.ToString(field) + " in " + doc + "), product of:"); Explanation tfExpl = Scorer(reader, true, false).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]):1.0f; fieldNormExpl.SetValue(fieldNorm); fieldNormExpl.SetDescription("fieldNorm(field=" + field + ", doc=" + doc + ")"); fieldExpl.AddDetail(fieldNormExpl); fieldExpl.SetMatch(tfExpl.IsMatch()); fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); System.Boolean? tempAux = fieldExpl.GetMatch(); result.SetMatch(tempAux); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) return fieldExpl; return result; }
public virtual Explanation Explain(params float[] scores) { Explanation expl = new Explanation(); float boost = 1.0f; foreach (float score in scores) { boost *= score; } expl.Value = boost; expl.Description = "product of: " + Arrays.ToString(scores); return expl; }
public virtual Explanation Explain(params float[] scores) { Explanation expl = new Explanation(); float sum = 0.0f; foreach (float score in scores) { sum += score; } expl.Value = sum; expl.Description = "sum of: " + Arrays.ToString(scores); return expl; }
public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) { float valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.Value; Explanation exp = new Explanation(valSrcScore + subQueryExpl.Value, "custom score: sum of:"); exp.AddDetail(subQueryExpl); if (valSrcExpl != null) { exp.AddDetail(valSrcExpl); } return(exp); }
public ExplanationDialog(Explanation e) { // // Required for Windows Form Designer support // InitializeComponent(); treeExplain.BeginUpdate(); AddNode(null, e); treeExplain.ExpandAll(); treeExplain.EndUpdate(); }
public override Explanation Explain(int doc) { Explanation tfExplanation = new Explanation(); while (Next() && Doc() < doc) { } float phraseFreq = (Doc() == doc)?freq:0.0f; tfExplanation.SetValue(GetSimilarity().Tf(phraseFreq)); tfExplanation.SetDescription("tf(phraseFreq=" + phraseFreq + ")"); return tfExplanation; }
public override Explanation Explain(int doc) { // make sure it has minX and area if (validMinX.Get(doc) && validMaxX.Get(doc)) { Rectangle rect = new RectangleImpl( minX[doc], maxX[doc], minY[doc], maxY[doc]); var exp = new Explanation(); _enclosingInstance.similarity.Score(rect, exp); return exp; } return new Explanation(0, "No BBox"); }
public override Explanation Explain(int doc) { Explanation res = new Explanation(); if (exclScorer.SkipTo(doc) && (exclScorer.Doc() == doc)) { res.SetDescription("excluded"); } else { res.SetDescription("not excluded"); res.AddDetail(reqScorer.Explain(doc)); } return res; }
public override Explanation Explain(IndexSearcher searcher, Explanation firstPassExplanation, int docID) { Explanation result = base.Explain(searcher, firstPassExplanation, docID); IList<AtomicReaderContext> leaves = searcher.IndexReader.Leaves; int subReader = ReaderUtil.SubIndex(docID, leaves); AtomicReaderContext readerContext = leaves[subReader]; int docIDInSegment = docID - readerContext.DocBase; var context = new Dictionary<string, object>(); var fakeScorer = new FakeScorer { score = firstPassExplanation.Value, doc = docIDInSegment }; context["scorer"] = fakeScorer; foreach (string variable in expression.variables) { result.AddDetail(new Explanation((float)bindings.GetValueSource(variable).GetValues (context, readerContext).DoubleVal(docIDInSegment), "variable \"" + variable + "\"" )); } return result; }
public double Score(Rectangle indexRect, Explanation exp) { double score; if (indexRect == null) { score = nullValue; } else { score = distCalc.Distance(queryPoint, indexRect.GetCenter()); } if (exp != null) { exp.Value = (float) score; exp.Description = GetType().Name; exp.AddDetail(new Explanation(-1f, "" + queryPoint)); exp.AddDetail(new Explanation(-1f, "" + indexRect)); } return score; }
public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[] valSrcExpls) { if (valSrcExpls.Length == 0) { return(subQueryExpl); } Explanation exp = new Explanation(valSrcExpls[0].Value + subQueryExpl.Value, "sum of:"); exp.AddDetail(subQueryExpl); exp.AddDetail(valSrcExpls[0]); if (valSrcExpls.Length == 1) { exp.Description = "CustomMulAdd, sum of:"; return(exp); } Explanation exp2 = new Explanation(valSrcExpls[1].Value * exp.Value, "custom score: product of:"); exp2.AddDetail(valSrcExpls[1]); exp2.AddDetail(exp); return(exp2); }
private void btnExplain_Click(object sender, System.EventArgs e) { if (listSearch.SelectedItems.Count == 0) { return; } if (searchedDocIds == null || searchedDocIds.Length < listSearch.Items.Count) { return; } if (_luke.IndexReader == null) { _luke.ShowStatus(_luke.resources.GetString("NoIndex")); return; } if (query == null) { return; } IndexSearcher searcher = null; try { searcher = new IndexSearcher(_luke.Directory, true); Lucene.Net.Search.Explanation expl = searcher.Explain(query, searchedDocIds[listSearch.SelectedIndices[0]]); ExplanationDialog explDialog = new ExplanationDialog(expl); explDialog.ShowDialog(this); } catch (Exception exc) { _luke.ErrorMessage(exc.Message); } finally { searcher.Close(); } }
private void AddNode(TreeNode tn, Explanation e) { TreeNode node = new TreeNode(e.GetValue().ToString("G4") + " " + e.GetDescription()); if (null == tn) { treeExplain.Nodes.Add(node); } else { tn.Nodes.Add(node); } Explanation[] kids = e.GetDetails(); if (kids != null && kids.Length > 0) { for (int i = 0; i < kids.Length; i++) { AddNode(node, kids[i]); } } }
private void Explain(LNS.Query query) { int j = 0; while (j < collector.Array.Count) { int i; i = collector.Array.GetNextTrueIndex(j); if (i >= collector.Array.Count) { break; } j = i + 1; Document doc = searcher.Doc(i); LNS.Explanation exp = searcher.Explain(query, i); Log.Debug("Query: [{0}]", query); Log.Debug("Matching URI: {0}", doc.Get("Uri")); Log.Debug("Explanation: {0}", exp); } }
protected void Page_Load(object sender, EventArgs e) { if (Request.QueryString.Count == 4 && Request.QueryString.AllKeys[0] == "query" && Request.QueryString.AllKeys[1] == "absoluteUri" && Request.QueryString.AllKeys[2] == "documentID" && Request.QueryString.AllKeys[3] == "strength") { Query query; if (!Request.QueryString.AllKeys[0].Contains(":")) { query = Global.DefaultQueryParser.Parse(Request.QueryString.AllKeys[0]); } else { query = Global.CustomQueryParser.Parse(Request.QueryString.AllKeys[0]); } uxHlAbsoluteUri.NavigateUrl = Request.QueryString[1]; uxHlAbsoluteUri.Text = Request.QueryString[1]; Lucene.Net.Search.Explanation explanation = Global.IndexSearcher.Explain(query, int.Parse(Request.QueryString[2])); uxLblExplanation.Text = explanation.ToHtml(); uxLblStrength.Text = "<ul><li>Strength: " + Request.QueryString[3] + "</li></ul>"; } }
public override Explanation Explain(IndexReader reader, int doc) { ComplexExplanation result = new ComplexExplanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); Explanation expl = new Explanation(idf, idfExp.Explain()); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:"); Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost"); if (Enclosing_Instance.GetBoost() != 1.0f) { queryExpl.AddDetail(boostExpl); } queryExpl.AddDetail(expl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.AddDetail(queryNormExpl); queryExpl.SetValue(boostExpl.GetValue() * expl.GetValue() * queryNormExpl.GetValue()); result.AddDetail(queryExpl); // explain field weight System.String field = Enclosing_Instance.term.Field(); ComplexExplanation fieldExpl = new ComplexExplanation(); fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.term + " in " + doc + "), product of:"); Explanation tfExpl = Scorer(reader, true, false).Explain(doc); fieldExpl.AddDetail(tfExpl); fieldExpl.AddDetail(expl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 1.0f; fieldNormExpl.SetValue(fieldNorm); fieldNormExpl.SetDescription("fieldNorm(field=" + field + ", doc=" + doc + ")"); fieldExpl.AddDetail(fieldNormExpl); fieldExpl.SetMatch(tfExpl.IsMatch()); fieldExpl.SetValue(tfExpl.GetValue() * expl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); System.Boolean?tempAux = fieldExpl.GetMatch(); result.SetMatch(tempAux); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) { return(fieldExpl); } return(result); }
public virtual Explanation Explain(IndexReader reader, int doc) { // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("MatchAllDocsQuery:"); Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost"); if (Enclosing_Instance.GetBoost() != 1.0f) queryExpl.AddDetail(boostExpl); queryExpl.SetValue(boostExpl.GetValue()); return queryExpl; }
/// <summary>Returns an explanation of the score for a document. /// <br>When this method is used, the {@link #next()} method /// and the {@link #Score(HitCollector)} method should not be used. /// </summary> /// <param name="doc">The document number for the explanation. /// </param> public override Explanation Explain(int doc) { TermQuery query = (TermQuery) weight.GetQuery(); Explanation tfExplanation = new Explanation(); int tf = 0; while (pointer < pointerMax) { if (docs[pointer] == doc) tf = freqs[pointer]; pointer++; } if (tf == 0) { if (termDocs.SkipTo(doc)) { if (termDocs.Doc() == doc) { tf = termDocs.Freq(); } } } termDocs.Close(); tfExplanation.SetValue(GetSimilarity().Tf(tf)); tfExplanation.SetDescription("tf(termFreq(" + query.GetTerm() + ")=" + tf + ")"); return tfExplanation; }
public override Explanation Explain(IndexReader reader, int doc) { Explanation result = new Explanation(); result.Description = "weight(" + Query + " in " + doc + "), product of:"; System.Text.StringBuilder docFreqs = new System.Text.StringBuilder(); System.Text.StringBuilder query = new System.Text.StringBuilder(); query.Append('\"'); docFreqs.Append(idfExp.Explain()); for (int i = 0; i < Enclosing_Instance.terms.Count; i++) { if (i != 0) { query.Append(" "); } Term term = Enclosing_Instance.terms[i]; query.Append(term.Text); } query.Append('\"'); Explanation idfExpl = new Explanation(idf, "idf(" + Enclosing_Instance.field + ":" + docFreqs + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.Description = "queryWeight(" + Query + "), product of:"; Explanation boostExpl = new Explanation(Enclosing_Instance.Boost, "boost"); if (Enclosing_Instance.Boost != 1.0f) { queryExpl.AddDetail(boostExpl); } queryExpl.AddDetail(idfExpl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.AddDetail(queryNormExpl); queryExpl.Value = boostExpl.Value * idfExpl.Value * queryNormExpl.Value; result.AddDetail(queryExpl); // explain field weight Explanation fieldExpl = new Explanation(); fieldExpl.Description = "fieldWeight(" + Enclosing_Instance.field + ":" + query + " in " + doc + "), product of:"; PhraseScorer scorer = (PhraseScorer)Scorer(reader, true, false); if (scorer == null) { return(new Explanation(0.0f, "no matching docs")); } Explanation tfExplanation = new Explanation(); int d = scorer.Advance(doc); float phraseFreq = (d == doc) ? scorer.CurrentFreq() : 0.0f; tfExplanation.Value = similarity.Tf(phraseFreq); tfExplanation.Description = "tf(phraseFreq=" + phraseFreq + ")"; fieldExpl.AddDetail(tfExplanation); fieldExpl.AddDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(Enclosing_Instance.field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 1.0f; fieldNormExpl.Value = fieldNorm; fieldNormExpl.Description = "fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")"; fieldExpl.AddDetail(fieldNormExpl); fieldExpl.Value = tfExplanation.Value * idfExpl.Value * fieldNormExpl.Value; result.AddDetail(fieldExpl); // combine them result.Value = queryExpl.Value * fieldExpl.Value; if (queryExpl.Value == 1.0f) { return(fieldExpl); } return(result); }
public virtual Explanation Explain(IndexReader reader, int doc) { Explanation result = new Explanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); Explanation idfExpl = new Explanation(idf, "idf(docFreq=" + reader.DocFreq(Enclosing_Instance.term) + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:"); Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost"); if (Enclosing_Instance.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 System.String field = Enclosing_Instance.term.Field(); Explanation fieldExpl = new Explanation(); fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.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.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) { return(fieldExpl); } return(result); }
/// <summary>Adds a sub-node to this explanation node. </summary> public virtual void AddDetail(Explanation detail) { if (details == null) details = new List<Explanation>(); details.Add(detail); }
public override Explanation Explain(IndexReader reader, int doc) { int minShouldMatch = Enclosing_Instance.GetMinimumNumberShouldMatch(); ComplexExplanation sumExpl = new ComplexExplanation(); sumExpl.SetDescription("sum of:"); int coord = 0; int maxCoord = 0; float sum = 0.0f; bool fail = false; int shouldMatchCount = 0; for (System.Collections.IEnumerator wIter = weights.GetEnumerator(), cIter = Enclosing_Instance.clauses.GetEnumerator(); wIter.MoveNext();) { cIter.MoveNext(); Weight w = (Weight)wIter.Current; BooleanClause c = (BooleanClause)cIter.Current; if (w.Scorer(reader, true, true) == null) { continue; } Explanation e = w.Explain(reader, doc); if (!c.IsProhibited()) { maxCoord++; } if (e.IsMatch()) { if (!c.IsProhibited()) { sumExpl.AddDetail(e); sum += e.GetValue(); coord++; } else { Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.GetQuery().ToString() + ")"); r.AddDetail(e); sumExpl.AddDetail(r); fail = true; } if (c.GetOccur() == Occur.SHOULD) { shouldMatchCount++; } } else if (c.IsRequired()) { Explanation r = new Explanation(0.0f, "no match on required clause (" + c.GetQuery().ToString() + ")"); r.AddDetail(e); sumExpl.AddDetail(r); fail = true; } } if (fail) { System.Boolean tempAux = false; sumExpl.SetMatch(tempAux); sumExpl.SetValue(0.0f); sumExpl.SetDescription("Failure to meet condition(s) of required/prohibited clause(s)"); return(sumExpl); } else if (shouldMatchCount < minShouldMatch) { System.Boolean tempAux2 = false; sumExpl.SetMatch(tempAux2); sumExpl.SetValue(0.0f); sumExpl.SetDescription("Failure to match minimum number " + "of optional clauses: " + minShouldMatch); return(sumExpl); } sumExpl.SetMatch(0 < coord?true:false); sumExpl.SetValue(sum); float coordFactor = similarity.Coord(coord, maxCoord); if (coordFactor == 1.0f) { // coord is no-op return(sumExpl); } // eliminate wrapper else { ComplexExplanation result = new ComplexExplanation(sumExpl.IsMatch(), sum * coordFactor, "product of:"); result.AddDetail(sumExpl); result.AddDetail(new Explanation(coordFactor, "coord(" + coord + "/" + maxCoord + ")")); return(result); } }
public virtual void TestTermQueryMultiSearcherExplain() { // creating two directories for indices Directory indexStoreA = new MockRAMDirectory(); Directory indexStoreB = new MockRAMDirectory(); Document lDoc = new Document(); lDoc.Add(new Field("handle", "1 2", Field.Store.YES, Field.Index.ANALYZED)); Document lDoc2 = new Document(); lDoc2.Add(new Field("handle", "1 2", Field.Store.YES, Field.Index.ANALYZED)); Document lDoc3 = new Document(); lDoc3.Add(new Field("handle", "1 2", Field.Store.YES, Field.Index.ANALYZED)); IndexWriter writerA = new IndexWriter(indexStoreA, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED); IndexWriter writerB = new IndexWriter(indexStoreB, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED); writerA.AddDocument(lDoc); writerA.AddDocument(lDoc2); writerA.Optimize(); writerA.Close(); writerB.AddDocument(lDoc3); writerB.Close(); QueryParser parser = new QueryParser(Util.Version.LUCENE_CURRENT, "fulltext", new StandardAnalyzer(Util.Version.LUCENE_CURRENT)); Query query = parser.Parse("handle:1"); Searcher[] searchers = new Searcher[2]; searchers[0] = new IndexSearcher(indexStoreB, true); searchers[1] = new IndexSearcher(indexStoreA, true); Searcher mSearcher = new MultiSearcher(searchers); ScoreDoc[] hits = mSearcher.Search(query, null, 1000).ScoreDocs; Assert.AreEqual(3, hits.Length); Explanation explain = mSearcher.Explain(query, hits[0].Doc); System.String exp = explain.ToString(0); Assert.IsTrue(exp.IndexOf("maxDocs=3") > -1, exp); Assert.IsTrue(exp.IndexOf("docFreq=3") > -1, exp); query = parser.Parse("handle:\"1 2\""); hits = mSearcher.Search(query, null, 1000).ScoreDocs; Assert.AreEqual(3, hits.Length); explain = mSearcher.Explain(query, hits[0].Doc); exp = explain.ToString(0); Assert.IsTrue(exp.IndexOf("1=3") > -1, exp); Assert.IsTrue(exp.IndexOf("2=3") > -1, exp); query = new SpanNearQuery(new SpanQuery[] { new SpanTermQuery(new Term("handle", "1")), new SpanTermQuery(new Term("handle", "2")) }, 0, true); hits = mSearcher.Search(query, null, 1000).ScoreDocs; Assert.AreEqual(3, hits.Length); explain = mSearcher.Explain(query, hits[0].Doc); exp = explain.ToString(0); Assert.IsTrue(exp.IndexOf("1=3") > -1, exp); Assert.IsTrue(exp.IndexOf("2=3") > -1, exp); mSearcher.Close(); }
public override Explanation Explain(IndexReader reader, int doc) { ComplexExplanation result = new ComplexExplanation(); result.Description = "weight(" + Query + " in " + doc + "), product of:"; Explanation expl = new Explanation(idf, idfExp.Explain()); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.Description = "queryWeight(" + Query + "), product of:"; Explanation boostExpl = new Explanation(Enclosing_Instance.Boost, "boost"); if (Enclosing_Instance.Boost != 1.0f) queryExpl.AddDetail(boostExpl); queryExpl.AddDetail(expl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.AddDetail(queryNormExpl); queryExpl.Value = boostExpl.Value * expl.Value * queryNormExpl.Value; result.AddDetail(queryExpl); // explain field weight System.String field = Enclosing_Instance.term.Field; ComplexExplanation fieldExpl = new ComplexExplanation(); fieldExpl.Description = "fieldWeight(" + Enclosing_Instance.term + " in " + doc + "), product of:"; Explanation tfExplanation = new Explanation(); int tf = 0; TermDocs termDocs = reader.TermDocs(enclosingInstance.term); if (termDocs != null) { try { if (termDocs.SkipTo(doc) && termDocs.Doc == doc) { tf = termDocs.Freq; } } finally { termDocs.Close(); } tfExplanation.Value = similarity.Tf(tf); tfExplanation.Description = "tf(termFreq(" + enclosingInstance.term + ")=" + tf + ")"; } else { tfExplanation.Value = 0.0f; tfExplanation.Description = "no matching term"; } fieldExpl.AddDetail(tfExplanation); fieldExpl.AddDetail(expl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):1.0f; fieldNormExpl.Value = fieldNorm; fieldNormExpl.Description = "fieldNorm(field=" + field + ", doc=" + doc + ")"; fieldExpl.AddDetail(fieldNormExpl); fieldExpl.Match = tfExplanation.IsMatch; fieldExpl.Value = tfExplanation.Value * expl.Value * fieldNormExpl.Value; result.AddDetail(fieldExpl); System.Boolean? tempAux = fieldExpl.Match; result.Match = tempAux; // combine them result.Value = queryExpl.Value * fieldExpl.Value; if (queryExpl.Value == 1.0f) return fieldExpl; return result; }
public virtual void TestExplain() { Directory dir = NewDirectory(); RandomIndexWriter w = new RandomIndexWriter(Random(), dir, Similarity, TimeZone); Document doc = new Document(); doc.Add(NewStringField("id", "0", Field.Store.YES)); doc.Add(NewTextField("field", "wizard the the the the the oz", Field.Store.NO)); w.AddDocument(doc); doc = new Document(); doc.Add(NewStringField("id", "1", Field.Store.YES)); // 1 extra token, but wizard and oz are close; doc.Add(NewTextField("field", "wizard oz the the the the the the", Field.Store.NO)); w.AddDocument(doc); IndexReader r = w.Reader; w.Dispose(); // Do ordinary BooleanQuery: BooleanQuery bq = new BooleanQuery(); bq.Add(new TermQuery(new Term("field", "wizard")), Occur.SHOULD); bq.Add(new TermQuery(new Term("field", "oz")), Occur.SHOULD); IndexSearcher searcher = GetSearcher(r); TopDocs hits = searcher.Search(bq, 10); Assert.AreEqual(2, hits.TotalHits); Assert.AreEqual("0", searcher.Doc(hits.ScoreDocs[0].Doc).Get("id")); Assert.AreEqual("1", searcher.Doc(hits.ScoreDocs[1].Doc).Get("id")); // Now, resort using PhraseQuery: PhraseQuery pq = new PhraseQuery(); pq.Add(new Term("field", "wizard")); pq.Add(new Term("field", "oz")); Rescorer rescorer = new QueryRescorerAnonymousInnerClassHelper2(this, pq); TopDocs hits2 = rescorer.Rescore(searcher, hits, 10); // Resorting changed the order: Assert.AreEqual(2, hits2.TotalHits); Assert.AreEqual("1", searcher.Doc(hits2.ScoreDocs[0].Doc).Get("id")); Assert.AreEqual("0", searcher.Doc(hits2.ScoreDocs[1].Doc).Get("id")); int docID = hits2.ScoreDocs[0].Doc; Explanation explain = rescorer.Explain(searcher, searcher.Explain(bq, docID), docID); string s = explain.ToString(); Assert.IsTrue(s.Contains("TestQueryRescorer+")); Assert.IsTrue(s.Contains("combined first and second pass score")); Assert.IsTrue(s.Contains("first pass score")); Assert.IsTrue(s.Contains("= second pass score")); Assert.AreEqual(hits2.ScoreDocs[0].Score, explain.Value, 0.0f); docID = hits2.ScoreDocs[1].Doc; explain = rescorer.Explain(searcher, searcher.Explain(bq, docID), docID); s = explain.ToString(); Assert.IsTrue(s.Contains("TestQueryRescorer+")); Assert.IsTrue(s.Contains("combined first and second pass score")); Assert.IsTrue(s.Contains("first pass score")); Assert.IsTrue(s.Contains("no second pass score")); Assert.IsFalse(s.Contains("= second pass score")); Assert.IsTrue(s.Contains("NON-MATCH")); Assert.IsTrue(Math.Abs(hits2.ScoreDocs[1].Score - explain.Value) < 0.0000001f); r.Dispose(); dir.Dispose(); }
/// <summary> /// Assert that an explanation has the expected score, and optionally that its /// sub-details max/sum/factor match to that score. /// </summary> /// <param name="q"> String representation of the query for assertion messages. </param> /// <param name="doc"> Document ID for assertion messages. </param> /// <param name="score"> Real score value of doc with query <paramref name="q"/>. </param> /// <param name="deep"> Indicates whether a deep comparison of sub-Explanation details should be executed. </param> /// <param name="expl"> The <see cref="Explanation"/> to match against score. </param> public static void VerifyExplanation(string q, int doc, float score, bool deep, Explanation expl) { float value = expl.Value; Assert.AreEqual(score, value, ExplainToleranceDelta(score, value), q + ": score(doc=" + doc + ")=" + score + " != explanationScore=" + value + " Explanation: " + expl); if (!deep) { return; } Explanation[] detail = expl.GetDetails(); // TODO: can we improve this entire method? its really geared to work only with TF/IDF if (expl.Description.EndsWith("computed from:", StringComparison.Ordinal)) { return; // something more complicated. } if (detail != null) { if (detail.Length == 1) { // simple containment, unless its a freq of: (which lets a query explain how the freq is calculated), // just verify contained expl has same score if (!expl.Description.EndsWith("with freq of:", StringComparison.Ordinal)) { VerifyExplanation(q, doc, score, deep, detail[0]); } } else { // explanation must either: // - end with one of: "product of:", "sum of:", "max of:", or // - have "max plus <x> times others" (where <x> is float). float x = 0; string descr = CultureInfo.InvariantCulture.TextInfo.ToLower(expl.Description); bool productOf = descr.EndsWith("product of:", StringComparison.Ordinal); bool sumOf = descr.EndsWith("sum of:", StringComparison.Ordinal); bool maxOf = descr.EndsWith("max of:", StringComparison.Ordinal); bool maxTimesOthers = false; if (!(productOf || sumOf || maxOf)) { // maybe 'max plus x times others' int k1 = descr.IndexOf("max plus ", StringComparison.Ordinal); if (k1 >= 0) { k1 += "max plus ".Length; int k2 = descr.IndexOf(" ", k1, StringComparison.Ordinal); // LUCENENET NOTE: Using current culture here is intentional because // we are parsing from text that was made using the current culture. if (float.TryParse(descr.Substring(k1, k2 - k1).Trim(), out x) && descr.Substring(k2).Trim().Equals("times others of:", StringComparison.Ordinal)) { maxTimesOthers = true; } } } // TODO: this is a TERRIBLE assertion!!!! Assert.IsTrue(productOf || sumOf || maxOf || maxTimesOthers, q + ": multi valued explanation description=\"" + descr + "\" must be 'max of plus x times others' or end with 'product of'" + " or 'sum of:' or 'max of:' - " + expl); float sum = 0; float product = 1; float max = 0; for (int i = 0; i < detail.Length; i++) { float dval = detail[i].Value; VerifyExplanation(q, doc, dval, deep, detail[i]); product *= dval; sum += dval; max = Math.Max(max, dval); } float combined = 0; if (productOf) { combined = product; } else if (sumOf) { combined = sum; } else if (maxOf) { combined = max; } else if (maxTimesOthers) { combined = max + x * (sum - max); } else { Assert.IsTrue(false, "should never get here!"); } Assert.AreEqual(combined, value, ExplainToleranceDelta(combined, value), q + ": actual subDetails combined==" + combined + " != value=" + value + " Explanation: " + expl); } } }
public override Explanation Explain(IndexReader reader, int doc) { ComplexExplanation result = new ComplexExplanation(); result.Description = "weight(" + Query + " in " + doc + "), product of:"; Explanation idfExpl = new Explanation(idf, "idf(" + Query + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.Description = "queryWeight(" + Query + "), product of:"; Explanation boostExpl = new Explanation(Enclosing_Instance.Boost, "boost"); if (Enclosing_Instance.Boost != 1.0f) { queryExpl.AddDetail(boostExpl); } queryExpl.AddDetail(idfExpl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.AddDetail(queryNormExpl); queryExpl.Value = boostExpl.Value * idfExpl.Value * queryNormExpl.Value; result.AddDetail(queryExpl); // explain field weight ComplexExplanation fieldExpl = new ComplexExplanation(); fieldExpl.Description = "fieldWeight(" + Query + " in " + doc + "), product of:"; PhraseScorer scorer = (PhraseScorer)Scorer(reader, true, false); if (scorer == null) { return(new Explanation(0.0f, "no matching docs")); } Explanation tfExplanation = new Explanation(); int d = scorer.Advance(doc); float phraseFreq = (d == doc) ? scorer.CurrentFreq() : 0.0f; tfExplanation.Value = similarity.Tf(phraseFreq); tfExplanation.Description = "tf(phraseFreq=" + phraseFreq + ")"; fieldExpl.AddDetail(tfExplanation); fieldExpl.AddDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(Enclosing_Instance.field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 1.0f; fieldNormExpl.Value = fieldNorm; fieldNormExpl.Description = "fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")"; fieldExpl.AddDetail(fieldNormExpl); fieldExpl.Match = tfExplanation.IsMatch; fieldExpl.Value = tfExplanation.Value * idfExpl.Value * fieldNormExpl.Value; result.AddDetail(fieldExpl); System.Boolean?tempAux = fieldExpl.Match; result.Match = tempAux; // combine them result.Value = queryExpl.Value * fieldExpl.Value; if (queryExpl.Value == 1.0f) { return(fieldExpl); } return(result); }
/// <summary>Adds a sub-node to this explanation node. </summary> public virtual void AddDetail(Explanation detail) { if (details == null) details = new System.Collections.ArrayList(); details.Add(detail); }
public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) { float valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.Value; Explanation exp = new Explanation(valSrcScore + subQueryExpl.Value, "custom score: sum of:"); exp.AddDetail(subQueryExpl); if (valSrcExpl != null) { exp.AddDetail(valSrcExpl); } return exp; }
public virtual Explanation Explain(IndexReader reader, int doc) { Explanation result = new Explanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); System.Text.StringBuilder docFreqs = new System.Text.StringBuilder(); System.Text.StringBuilder query = new System.Text.StringBuilder(); query.Append('\"'); for (int i = 0; i < Enclosing_Instance.terms.Count; i++) { if (i != 0) { docFreqs.Append(" "); query.Append(" "); } Term term = (Term)Enclosing_Instance.terms[i]; docFreqs.Append(term.Text()); docFreqs.Append("="); docFreqs.Append(reader.DocFreq(term)); query.Append(term.Text()); } query.Append('\"'); Explanation idfExpl = new Explanation(idf, "idf(" + Enclosing_Instance.field + ": " + docFreqs + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:"); Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost"); if (Enclosing_Instance.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 Explanation fieldExpl = new Explanation(); fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.field + ":" + query + " in " + doc + "), product of:"); Explanation tfExpl = Scorer(reader).Explain(doc); fieldExpl.AddDetail(tfExpl); fieldExpl.AddDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(Enclosing_Instance.field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f; fieldNormExpl.SetValue(fieldNorm); fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")"); fieldExpl.AddDetail(fieldNormExpl); fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) { return(fieldExpl); } return(result); }
public virtual Explanation Explain(IndexReader reader, int doc) { Explanation result = new Explanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); System.Text.StringBuilder docFreqs = new System.Text.StringBuilder(); System.Text.StringBuilder query = new System.Text.StringBuilder(); query.Append('\"'); for (int i = 0; i < Enclosing_Instance.terms.Count; i++) { if (i != 0) { docFreqs.Append(" "); query.Append(" "); } Term term = (Term) Enclosing_Instance.terms[i]; docFreqs.Append(term.Text()); docFreqs.Append("="); docFreqs.Append(reader.DocFreq(term)); query.Append(term.Text()); } query.Append('\"'); Explanation idfExpl = new Explanation(idf, "idf(" + Enclosing_Instance.field + ": " + docFreqs + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:"); Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost"); if (Enclosing_Instance.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 Explanation fieldExpl = new Explanation(); fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.field + ":" + query + " in " + doc + "), product of:"); Explanation tfExpl = Scorer(reader).Explain(doc); fieldExpl.AddDetail(tfExpl); fieldExpl.AddDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(Enclosing_Instance.field); float fieldNorm = fieldNorms != null ? Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f; fieldNormExpl.SetValue(fieldNorm); fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")"); fieldExpl.AddDetail(fieldNormExpl); fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) return fieldExpl; return result; }
/// <summary> Assert that an explanation has the expected score, and optionally that its /// sub-details max/sum/factor match to that score. /// /// </summary> /// <param name="q">String representation of the query for assertion messages /// </param> /// <param name="doc">Document ID for assertion messages /// </param> /// <param name="score">Real score value of doc with query q /// </param> /// <param name="deep">indicates whether a deep comparison of sub-Explanation details should be executed /// </param> /// <param name="expl">The Explanation to match against score /// </param> public static void VerifyExplanation(System.String q, int doc, float score, bool deep, Explanation expl) { float value_Renamed = expl.Value; Assert.AreEqual(score, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": score(doc=" + doc + ")=" + score + " != explanationScore=" + value_Renamed + " Explanation: " + expl); if (!deep) { return; } Explanation[] detail = expl.GetDetails(); if (detail != null) { if (detail.Length == 1) { // simple containment, no matter what the description says, // just verify contained expl has same score VerifyExplanation(q, doc, score, deep, detail[0]); } else { // explanation must either: // - end with one of: "product of:", "sum of:", "max of:", or // - have "max plus <x> times others" (where <x> is float). float x = 0; System.String descr = expl.Description.ToLower(); bool productOf = descr.EndsWith("product of:"); bool sumOf = descr.EndsWith("sum of:"); bool maxOf = descr.EndsWith("max of:"); bool maxTimesOthers = false; if (!(productOf || sumOf || maxOf)) { // maybe 'max plus x times others' int k1 = descr.IndexOf("max plus "); if (k1 >= 0) { k1 += "max plus ".Length; int k2 = descr.IndexOf(" ", k1); try { x = Single.Parse(descr.Substring(k1, (k2) - (k1)).Trim()); if (descr.Substring(k2).Trim().Equals("times others of:")) { maxTimesOthers = true; } } catch (System.FormatException) { } } } Assert.IsTrue(productOf || sumOf || maxOf || maxTimesOthers, q + ": multi valued explanation description=\"" + descr + "\" must be 'max of plus x times others' or end with 'product of'" + " or 'sum of:' or 'max of:' - " + expl); float sum = 0; float product = 1; float max = 0; for (int i = 0; i < detail.Length; i++) { float dval = detail[i].Value; VerifyExplanation(q, doc, dval, deep, detail[i]); product *= dval; sum += dval; max = System.Math.Max(max, dval); } float combined = 0; if (productOf) { combined = product; } else if (sumOf) { combined = sum; } else if (maxOf) { combined = max; } else if (maxTimesOthers) { combined = max + x * (sum - max); } else { Assert.IsTrue(false, "should never get here!"); } Assert.AreEqual(combined, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": actual subDetails combined==" + combined + " != value=" + value_Renamed + " Explanation: " + expl); } } }
public virtual Explanation Explain(IndexReader reader, int doc) { ComplexExplanation result = new ComplexExplanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); System.String field = ((SpanQuery) GetQuery()).GetField(); System.Text.StringBuilder docFreqs = new System.Text.StringBuilder(); System.Collections.IEnumerator i = terms.GetEnumerator(); while (i.MoveNext()) { System.Collections.DictionaryEntry tmp = (System.Collections.DictionaryEntry) i.Current; Term term = (Term) tmp.Key; docFreqs.Append(term.Text()); docFreqs.Append("="); docFreqs.Append(reader.DocFreq(term)); if (i.MoveNext()) { docFreqs.Append(" "); } } Explanation idfExpl = new Explanation(idf, "idf(" + field + ": " + docFreqs + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:"); Explanation boostExpl = new Explanation(GetQuery().GetBoost(), "boost"); if (GetQuery().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(" + field + ":" + query.ToString(field) + " 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(tfExpl.IsMatch()); fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); System.Boolean tempAux = fieldExpl.GetMatch(); result.SetMatch(tempAux); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) return fieldExpl; return result; }
public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[] valSrcExpls) { if (valSrcExpls.Length == 0) { return subQueryExpl; } Explanation exp = new Explanation(valSrcExpls[0].Value + subQueryExpl.Value, "sum of:"); exp.AddDetail(subQueryExpl); exp.AddDetail(valSrcExpls[0]); if (valSrcExpls.Length == 1) { exp.Description = "CustomMulAdd, sum of:"; return exp; } Explanation exp2 = new Explanation(valSrcExpls[1].Value * exp.Value, "custom score: product of:"); exp2.AddDetail(valSrcExpls[1]); exp2.AddDetail(exp); return exp2; }
internal virtual Explanation DoExplain(AtomicReaderContext info, int doc) { var subQueryExpl = subQueryWeight.Explain(info, doc); if (!subQueryExpl.IsMatch) { return subQueryExpl; } // match var valSrcExpls = new Explanation[valSrcWeights.Length]; for (int i = 0; i < valSrcWeights.Length; i++) { valSrcExpls[i] = valSrcWeights[i].Explain(info, doc); } Explanation customExp = outerInstance.GetCustomScoreProvider(info) .CustomExplain(doc, subQueryExpl, valSrcExpls); float sc = outerInstance.Boost * customExp.Value; Explanation res = new ComplexExplanation(true, sc, outerInstance.ToString() + ", product of:"); res.AddDetail(customExp); res.AddDetail(new Explanation(outerInstance.Boost, "queryBoost")); // actually using the q boost as q weight (== weight value) return res; }
public virtual Explanation Explain(IndexReader reader, int doc) { Explanation result = new Explanation(); result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:"); Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")"); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:"); Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost"); if (Enclosing_Instance.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 Explanation fieldExpl = new Explanation(); fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:"); Explanation tfExpl = Scorer(reader).Explain(doc); fieldExpl.AddDetail(tfExpl); fieldExpl.AddDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(Enclosing_Instance.field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):0.0f; fieldNormExpl.SetValue(fieldNorm); fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")"); fieldExpl.AddDetail(fieldNormExpl); fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue()); result.AddDetail(fieldExpl); // combine them result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue()); if (queryExpl.GetValue() == 1.0f) return fieldExpl; return result; }
public double Score(Rectangle target, Explanation exp) { if (target == null || queryArea <= 0) { return 0; } double targetArea = target.GetArea(null); if (targetArea <= 0) { return 0; } double score = 0; double top = Math.Min(queryExtent.GetMaxY(), target.GetMaxY()); double bottom = Math.Max(queryExtent.GetMinY(), target.GetMinY()); double height = top - bottom; double width = 0; // queries that cross the date line if (queryExtent.GetCrossesDateLine()) { // documents that cross the date line if (target.GetCrossesDateLine()) { double left = Math.Max(queryExtent.GetMinX(), target.GetMinX()); double right = Math.Min(queryExtent.GetMaxX(), target.GetMaxX()); width = right + 360.0 - left; } else { double qryWestLeft = Math.Max(queryExtent.GetMinX(), target.GetMaxX()); double qryWestRight = Math.Min(target.GetMaxX(), 180.0); double qryWestWidth = qryWestRight - qryWestLeft; if (qryWestWidth > 0) { width = qryWestWidth; } else { double qryEastLeft = Math.Max(target.GetMaxX(), -180.0); double qryEastRight = Math.Min(queryExtent.GetMaxX(), target.GetMaxX()); double qryEastWidth = qryEastRight - qryEastLeft; if (qryEastWidth > 0) { width = qryEastWidth; } } } } else { // queries that do not cross the date line if (target.GetCrossesDateLine()) { double tgtWestLeft = Math.Max(queryExtent.GetMinX(), target.GetMinX()); double tgtWestRight = Math.Min(queryExtent.GetMaxX(), 180.0); double tgtWestWidth = tgtWestRight - tgtWestLeft; if (tgtWestWidth > 0) { width = tgtWestWidth; } else { double tgtEastLeft = Math.Max(queryExtent.GetMinX(), -180.0); double tgtEastRight = Math.Min(queryExtent.GetMaxX(), target.GetMaxX()); double tgtEastWidth = tgtEastRight - tgtEastLeft; if (tgtEastWidth > 0) { width = tgtEastWidth; } } } else { double left = Math.Max(queryExtent.GetMinX(), target.GetMinX()); double right = Math.Min(queryExtent.GetMaxX(), target.GetMaxX()); width = right - left; } } // calculate the score if ((width > 0) && (height > 0)) { double intersectionArea = width * height; double queryRatio = intersectionArea / queryArea; double targetRatio = intersectionArea / targetArea; double queryFactor = Math.Pow(queryRatio, queryPower); double targetFactor = Math.Pow(targetRatio, targetPower); score = queryFactor * targetFactor * 10000.0; if (exp != null) { // StringBuilder sb = new StringBuilder(); // sb.append("\nscore=").append(score); // sb.append("\n query=").append(); // sb.append("\n target=").append(target.toString()); // sb.append("\n intersectionArea=").append(intersectionArea); // // sb.append(" queryArea=").append(queryArea).append(" targetArea=").append(targetArea); // sb.append("\n queryRatio=").append(queryRatio).append(" targetRatio=").append(targetRatio); // sb.append("\n queryFactor=").append(queryFactor).append(" targetFactor=").append(targetFactor); // sb.append(" (queryPower=").append(queryPower).append(" targetPower=").append(targetPower).append(")"); exp.Value = (float) score; exp.Description = GetType().Name; Explanation e = null; exp.AddDetail(e = new Explanation((float)intersectionArea, "IntersectionArea")); e.AddDetail(new Explanation((float)width, "width; Query: " + queryExtent)); e.AddDetail(new Explanation((float)height, "height; Target: " + target)); exp.AddDetail(e = new Explanation((float)queryFactor, "Query")); e.AddDetail(new Explanation((float)queryArea, "area")); e.AddDetail(new Explanation((float)queryRatio, "ratio")); e.AddDetail(new Explanation((float)queryPower, "power")); exp.AddDetail(e = new Explanation((float)targetFactor, "Target")); e.AddDetail(new Explanation((float)targetArea, "area")); e.AddDetail(new Explanation((float)targetRatio, "ratio")); e.AddDetail(new Explanation((float)targetPower, "power")); } } else if (exp != null) { exp.Value = 0; exp.Description = "Shape does not intersect"; } return score; }
public override Explanation Explain(AtomicReaderContext context, int doc) { int minShouldMatch = outerInstance.MinimumNumberShouldMatch; ComplexExplanation sumExpl = new ComplexExplanation(); sumExpl.Description = "sum of:"; int coord = 0; float sum = 0.0f; bool fail = false; int shouldMatchCount = 0; IEnumerator <BooleanClause> cIter = outerInstance.clauses.GetEnumerator(); for (IEnumerator <Weight> wIter = m_weights.GetEnumerator(); wIter.MoveNext();) { Weight w = wIter.Current; cIter.MoveNext(); BooleanClause c = cIter.Current; if (w.GetScorer(context, context.AtomicReader.LiveDocs) == null) { if (c.IsRequired) { fail = true; Explanation r = new Explanation(0.0f, "no match on required clause (" + c.Query.ToString() + ")"); sumExpl.AddDetail(r); } continue; } Explanation e = w.Explain(context, doc); if (e.IsMatch) { if (!c.IsProhibited) { sumExpl.AddDetail(e); sum += e.Value; coord++; } else { Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.Query.ToString() + ")"); r.AddDetail(e); sumExpl.AddDetail(r); fail = true; } if (c.Occur == Occur_e.SHOULD) { shouldMatchCount++; } } else if (c.IsRequired) { Explanation r = new Explanation(0.0f, "no match on required clause (" + c.Query.ToString() + ")"); r.AddDetail(e); sumExpl.AddDetail(r); fail = true; } } if (fail) { sumExpl.Match = false; sumExpl.Value = 0.0f; sumExpl.Description = "Failure to meet condition(s) of required/prohibited clause(s)"; return(sumExpl); } else if (shouldMatchCount < minShouldMatch) { sumExpl.Match = false; sumExpl.Value = 0.0f; sumExpl.Description = "Failure to match minimum number " + "of optional clauses: " + minShouldMatch; return(sumExpl); } sumExpl.Match = 0 < coord ? true : false; sumExpl.Value = sum; float coordFactor = disableCoord ? 1.0f : Coord(coord, m_maxCoord); if (coordFactor == 1.0f) { return(sumExpl); // eliminate wrapper } else { ComplexExplanation result = new ComplexExplanation(sumExpl.IsMatch, sum * coordFactor, "product of:"); result.AddDetail(sumExpl); result.AddDetail(new Explanation(coordFactor, "coord(" + coord + "/" + m_maxCoord + ")")); return(result); } }
public override Explanation Explain(IndexReader reader, int doc) { ComplexExplanation result = new ComplexExplanation(); result.Description = "weight(" + Query + " in " + doc + "), product of:"; Explanation expl = new Explanation(idf, idfExp.Explain()); // explain query weight Explanation queryExpl = new Explanation(); queryExpl.Description = "queryWeight(" + Query + "), product of:"; Explanation boostExpl = new Explanation(Enclosing_Instance.Boost, "boost"); if (Enclosing_Instance.Boost != 1.0f) { queryExpl.AddDetail(boostExpl); } queryExpl.AddDetail(expl); Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm"); queryExpl.AddDetail(queryNormExpl); queryExpl.Value = boostExpl.Value * expl.Value * queryNormExpl.Value; result.AddDetail(queryExpl); // explain field weight System.String field = Enclosing_Instance.term.Field; ComplexExplanation fieldExpl = new ComplexExplanation(); fieldExpl.Description = "fieldWeight(" + Enclosing_Instance.term + " in " + doc + "), product of:"; Explanation tfExplanation = new Explanation(); int tf = 0; TermDocs termDocs = reader.TermDocs(enclosingInstance.term); if (termDocs != null) { try { if (termDocs.SkipTo(doc) && termDocs.Doc == doc) { tf = termDocs.Freq; } } finally { termDocs.Close(); } tfExplanation.Value = similarity.Tf(tf); tfExplanation.Description = "tf(termFreq(" + enclosingInstance.term + ")=" + tf + ")"; } else { tfExplanation.Value = 0.0f; tfExplanation.Description = "no matching term"; } fieldExpl.AddDetail(tfExplanation); fieldExpl.AddDetail(expl); Explanation fieldNormExpl = new Explanation(); byte[] fieldNorms = reader.Norms(field); float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 1.0f; fieldNormExpl.Value = fieldNorm; fieldNormExpl.Description = "fieldNorm(field=" + field + ", doc=" + doc + ")"; fieldExpl.AddDetail(fieldNormExpl); fieldExpl.Match = tfExplanation.IsMatch; fieldExpl.Value = tfExplanation.Value * expl.Value * fieldNormExpl.Value; result.AddDetail(fieldExpl); System.Boolean?tempAux = fieldExpl.Match; result.Match = tempAux; // combine them result.Value = queryExpl.Value * fieldExpl.Value; if (queryExpl.Value == 1.0f) { return(fieldExpl); } return(result); }
public virtual Explanation Explain(IndexReader reader, int doc) { int minShouldMatch = Enclosing_Instance.GetMinimumNumberShouldMatch(); ComplexExplanation sumExpl = new ComplexExplanation(); sumExpl.SetDescription("sum of:"); int coord = 0; int maxCoord = 0; float sum = 0.0f; bool fail = false; int shouldMatchCount = 0; for (int i = 0; i < weights.Count; i++) { BooleanClause c = (BooleanClause) Enclosing_Instance.clauses[i]; Weight w = (Weight) weights[i]; Explanation e = w.Explain(reader, doc); if (!c.IsProhibited()) maxCoord++; if (e.IsMatch()) { if (!c.IsProhibited()) { sumExpl.AddDetail(e); sum += e.GetValue(); coord++; } else { Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.GetQuery().ToString() + ")"); r.AddDetail(e); sumExpl.AddDetail(r); fail = true; } if (c.GetOccur().Equals(Occur.SHOULD)) shouldMatchCount++; } else if (c.IsRequired()) { Explanation r = new Explanation(0.0f, "no match on required clause (" + c.GetQuery().ToString() + ")"); r.AddDetail(e); sumExpl.AddDetail(r); fail = true; } } if (fail) { System.Boolean tempAux = false; sumExpl.SetMatch(tempAux); sumExpl.SetValue(0.0f); sumExpl.SetDescription("Failure to meet condition(s) of required/prohibited clause(s)"); return sumExpl; } else if (shouldMatchCount < minShouldMatch) { System.Boolean tempAux2 = false; sumExpl.SetMatch(tempAux2); sumExpl.SetValue(0.0f); sumExpl.SetDescription("Failure to match minimum number " + "of optional clauses: " + minShouldMatch); return sumExpl; } sumExpl.SetMatch(0 < coord ? true : false); sumExpl.SetValue(sum); float coordFactor = similarity.Coord(coord, maxCoord); if (coordFactor == 1.0f) // coord is no-op return sumExpl; // eliminate wrapper else { ComplexExplanation result = new ComplexExplanation(sumExpl.IsMatch(), sum * coordFactor, "product of:"); result.AddDetail(sumExpl); result.AddDetail(new Explanation(coordFactor, "coord(" + coord + "/" + maxCoord + ")")); return result; } }
public virtual Explanation Explain(IndexReader reader, int doc) { Explanation sumExpl = new Explanation(); sumExpl.SetDescription("sum of:"); int coord = 0; int maxCoord = 0; float sum = 0.0f; for (int i = 0; i < weights.Count; i++) { BooleanClause c = (BooleanClause)Enclosing_Instance.clauses[i]; Weight w = (Weight)weights[i]; Explanation e = w.Explain(reader, doc); if (!c.IsProhibited()) { maxCoord++; } if (e.GetValue() > 0) { if (!c.IsProhibited()) { sumExpl.AddDetail(e); sum += e.GetValue(); coord++; } else { return(new Explanation(0.0f, "match prohibited")); } } else if (c.IsRequired()) { return(new Explanation(0.0f, "match required")); } } sumExpl.SetValue(sum); if (coord == 1) { // only one clause matched sumExpl = sumExpl.GetDetails()[0]; // eliminate wrapper } float coordFactor = similarity.Coord(coord, maxCoord); if (coordFactor == 1.0f) { // coord is no-op return(sumExpl); } // eliminate wrapper else { Explanation result = new Explanation(); result.SetDescription("product of:"); result.AddDetail(sumExpl); result.AddDetail(new Explanation(coordFactor, "coord(" + coord + "/" + maxCoord + ")")); result.SetValue(sum * coordFactor); return(result); } }