📄 checkhits.java
字号:
* Asserts that the explanation value for every document matching a * query corresponds with the true score. * * @see ExplanationAsserter * @see #checkExplanations(Query, String, Searcher, boolean) for a * "deep" testing of the explanation details. * * @param query the query to test * @param searcher the searcher to test the query against * @param defaultFieldName used for displaing the query in assertion messages */ public static void checkExplanations(Query query, String defaultFieldName, Searcher searcher) throws IOException { checkExplanations(query, defaultFieldName, searcher, false); } /** * Asserts that the explanation value for every document matching a * query corresponds with the true score. Optionally does "deep" * testing of the explanation details. * * @see ExplanationAsserter * @param query the query to test * @param searcher the searcher to test the query against * @param defaultFieldName used for displaing the query in assertion messages * @param deep indicates whether a deep comparison of sub-Explanation details should be executed */ public static void checkExplanations(Query query, String defaultFieldName, Searcher searcher, boolean deep) throws IOException { searcher.search(query, new ExplanationAsserter (query, defaultFieldName, searcher, deep)); } /** * Assert that an explanation has the expected score, and optionally that its * sub-details max/sum/factor match to that score. * * @param q String representation of the query for assertion messages * @param doc Document ID for assertion messages * @param score Real score value of doc with query q * @param deep indicates whether a deep comparison of sub-Explanation details should be executed * @param expl The Explanation to match against score */ public static void verifyExplanation(String q, int doc, float score, boolean deep, Explanation expl) { float value = expl.getValue(); TestCase.assertEquals(q+": score(doc="+doc+")="+score+ " != explanationScore="+value+" Explanation: "+expl, score,value,EXPLAIN_SCORE_TOLERANCE_DELTA); 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; String descr = expl.getDescription().toLowerCase(); boolean productOf = descr.endsWith("product of:"); boolean sumOf = descr.endsWith("sum of:"); boolean maxOf = descr.endsWith("max of:"); boolean 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 = Float.parseFloat(descr.substring(k1,k2).trim()); if (descr.substring(k2).trim().equals("times others of:")) { maxTimesOthers = true; } } catch (NumberFormatException e) { } } } TestCase.assertTrue( 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, productOf || sumOf || maxOf || maxTimesOthers); float sum = 0; float product = 1; float max = 0; for (int i=0; i<detail.length; i++) { float dval = detail[i].getValue(); 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 { TestCase.assertTrue("should never get here!",false); } TestCase.assertEquals(q+": actual subDetails combined=="+combined+ " != value="+value+" Explanation: "+expl, combined,value,EXPLAIN_SCORE_TOLERANCE_DELTA); } } } /** * an IndexSearcher that implicitly checks hte explanation of every match * whenever it executes a search. * * @see ExplanationAsserter */ public static class ExplanationAssertingSearcher extends IndexSearcher { public ExplanationAssertingSearcher(Directory d) throws IOException { super(d); } public ExplanationAssertingSearcher(IndexReader r) throws IOException { super(r); } protected void checkExplanations(Query q) throws IOException { super.search(q, null, new ExplanationAsserter (q, null, this)); } public Hits search(Query query, Filter filter) throws IOException { checkExplanations(query); return super.search(query,filter); } public Hits search(Query query, Sort sort) throws IOException { checkExplanations(query); return super.search(query,sort); } public Hits search(Query query, Filter filter, Sort sort) throws IOException { checkExplanations(query); return super.search(query,filter,sort); } public TopFieldDocs search(Query query, Filter filter, int n, Sort sort) throws IOException { checkExplanations(query); return super.search(query,filter,n,sort); } public void search(Query query, HitCollector results) throws IOException { checkExplanations(query); super.search(query,results); } public void search(Query query, Filter filter, HitCollector results) throws IOException { checkExplanations(query); super.search(query,filter, results); } public TopDocs search(Query query, Filter filter, int n) throws IOException { checkExplanations(query); return super.search(query,filter, n); } } /** * Asserts that the score explanation for every document matching a * query corresponds with the true score. * * NOTE: this HitCollector should only be used with the Query and Searcher * specified at when it is constructed. * * @see CheckHits#verifyExplanation */ public static class ExplanationAsserter extends HitCollector { /** * @deprecated * @see CheckHits#EXPLAIN_SCORE_TOLERANCE_DELTA */ public static float SCORE_TOLERANCE_DELTA = 0.00005f; Query q; Searcher s; String d; boolean deep; /** Constructs an instance which does shallow tests on the Explanation */ public ExplanationAsserter(Query q, String defaultFieldName, Searcher s) { this(q,defaultFieldName,s,false); } public ExplanationAsserter(Query q, String defaultFieldName, Searcher s, boolean deep) { this.q=q; this.s=s; this.d = q.toString(defaultFieldName); this.deep=deep; } public void collect(int doc, float score) { Explanation exp = null; try { exp = s.explain(q, doc); } catch (IOException e) { throw new RuntimeException ("exception in hitcollector of [["+d+"]] for #"+doc, e); } TestCase.assertNotNull("Explanation of [["+d+"]] for #"+doc+" is null", exp); verifyExplanation(d,doc,score,deep,exp); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -