TestCustomScoreQuerypublic class TestCustomScoreQuery extends FunctionTestSetup Test CustomScoreQuery search. |
Constructors Summary |
---|
public TestCustomScoreQuery(String name)
super(name);
|
Methods Summary |
---|
private void | doTestCustomScore(java.lang.String field, org.apache.lucene.search.function.FieldScoreQuery$Type tp, double dboost)
float boost = (float) dboost;
IndexSearcher s = new IndexSearcher(dir);
FieldScoreQuery qValSrc = new FieldScoreQuery(field,tp); // a query that would score by the field
QueryParser qp = new QueryParser(TEXT_FIELD,anlzr);
String qtxt = "bleeding person chain knowledge"; // from the doc texts in FunctionQuerySetup.
// regular (boolean) query.
Query q1 = qp.parse(qtxt);
log(q1);
// custom query, that should score the same as q1.
CustomScoreQuery q2CustomNeutral = new CustomScoreQuery(q1);
q2CustomNeutral.setBoost(boost);
log(q2CustomNeutral);
// custom query, that should (by default) multiply the scores of q1 by that of the field
CustomScoreQuery q3CustomMul = new CustomScoreQuery(q1,qValSrc);
q3CustomMul.setStrict(true);
q3CustomMul.setBoost(boost);
log(q3CustomMul);
// custom query, that should add the scores of q1 to that of the field
CustomScoreQuery q4CustomAdd = new CustomScoreQuery(q1,qValSrc) {
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
public String name() {
return "customAdd";
}
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
public float customScore(int doc, float subQueryScore, float valSrcScore) {
return subQueryScore + valSrcScore;
}
/* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
float valSrcScore = valSrcExpl==null ? 0 : valSrcExpl.getValue();
Explanation exp = new Explanation( valSrcScore + subQueryExpl.getValue(), "custom score: sum of:");
exp.addDetail(subQueryExpl);
if (valSrcExpl != null) {
exp.addDetail(valSrcExpl);
}
return exp;
}
};
q4CustomAdd.setStrict(true);
q4CustomAdd.setBoost(boost);
log(q4CustomAdd);
// custom query, that multiplies and adds the field score to that of q1
CustomScoreQuery q5CustomMulAdd = new CustomScoreQuery(q1,qValSrc) {
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
public String name() {
return "customMulAdd";
}
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
public float customScore(int doc, float subQueryScore, float valSrcScore) {
return (1 + subQueryScore) * valSrcScore;
}
/* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
Explanation exp = new Explanation(1 + subQueryExpl.getValue(), "sum of:");
exp.addDetail(subQueryExpl);
exp.addDetail(new Explanation(1,"const 1"));
if (valSrcExpl == null) {
exp.setDescription("CustomMulAdd, sum of:");
return exp;
}
Explanation exp2 = new Explanation(valSrcExpl.getValue() * exp.getValue(), "custom score: product of:");
exp2.addDetail(valSrcExpl);
exp2.addDetail(exp);
return exp2;
}
};
q5CustomMulAdd.setStrict(true);
q5CustomMulAdd.setBoost(boost);
log(q5CustomMulAdd);
// do al the searches
TopDocs td1 = s.search(q1,null,1000);
TopDocs td2CustomNeutral = s.search(q2CustomNeutral,null,1000);
TopDocs td3CustomMul = s.search(q3CustomMul,null,1000);
TopDocs td4CustomAdd = s.search(q4CustomAdd,null,1000);
TopDocs td5CustomMulAdd = s.search(q5CustomMulAdd,null,1000);
// put results in map so we can verify the scores although they have changed
HashMap h1 = topDocsToMap(td1);
HashMap h2CustomNeutral = topDocsToMap(td2CustomNeutral);
HashMap h3CustomMul = topDocsToMap(td3CustomMul);
HashMap h4CustomAdd = topDocsToMap(td4CustomAdd);
HashMap h5CustomMulAdd = topDocsToMap(td5CustomMulAdd);
verifyResults(boost, s,
h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd,
q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd);
| private void | logResult(java.lang.String msg, org.apache.lucene.search.IndexSearcher s, org.apache.lucene.search.Query q, int doc, float score1)
QueryUtils.check(q,s);
log(msg+" "+score1);
log("Explain by: "+q);
log(s.explain(q,doc));
| protected void | setUp()
// prepare a small index with just a few documents.
super.setUp();
| protected void | tearDown()
super.tearDown();
| public void | testCustomScoreByte()Test that CustomScoreQuery of Type.BYTE returns the expected scores.
// INT field values are small enough to be parsed as byte
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.BYTE,1.0);
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.BYTE,2.0);
| public void | testCustomScoreFloat()Test that CustomScoreQuery of Type.FLOAT returns the expected scores.
// INT field can be parsed as float
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.FLOAT,1.0);
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.FLOAT,5.0);
// same values, but in flot format
doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,1.0);
doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,6.0);
| public void | testCustomScoreInt()Test that CustomScoreQuery of Type.INT returns the expected scores.
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.INT,1.0);
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.INT,4.0);
| public void | testCustomScoreShort()Test that CustomScoreQuery of Type.SHORT returns the expected scores.
// INT field values are small enough to be parsed as short
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.SHORT,1.0);
doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.SHORT,3.0);
| private java.util.HashMap | topDocsToMap(org.apache.lucene.search.TopDocs td)
HashMap h = new HashMap();
for (int i=0; i<td.totalHits; i++) {
h.put(new Integer(td.scoreDocs[i].doc), new Float(td.scoreDocs[i].score));
}
return h;
| private void | verifyResults(float boost, org.apache.lucene.search.IndexSearcher s, java.util.HashMap h1, java.util.HashMap h2customNeutral, java.util.HashMap h3CustomMul, java.util.HashMap h4CustomAdd, java.util.HashMap h5CustomMulAdd, org.apache.lucene.search.Query q1, org.apache.lucene.search.Query q2, org.apache.lucene.search.Query q3, org.apache.lucene.search.Query q4, org.apache.lucene.search.Query q5)
// verify numbers of matches
log("#hits = "+h1.size());
assertEquals("queries should have same #hits",h1.size(),h2customNeutral.size());
assertEquals("queries should have same #hits",h1.size(),h3CustomMul.size());
assertEquals("queries should have same #hits",h1.size(),h4CustomAdd.size());
assertEquals("queries should have same #hits",h1.size(),h5CustomMulAdd.size());
// verify scores ratios
for (Iterator it = h1.keySet().iterator(); it.hasNext();) {
Integer x = (Integer) it.next();
int doc = x.intValue();
log("doc = "+doc);
float fieldScore = expectedFieldScore(s.getIndexReader().document(doc).get(ID_FIELD));
log("fieldScore = "+fieldScore);
assertTrue("fieldScore should not be 0",fieldScore>0);
float score1 = ((Float)h1.get(x)).floatValue();
logResult("score1=", s, q1, doc, score1);
float score2 = ((Float)h2customNeutral.get(x)).floatValue();
logResult("score2=", s, q2, doc, score2);
assertEquals("same score (just boosted) for neutral", boost * score1, score2, TEST_SCORE_TOLERANCE_DELTA);
float score3 = ((Float)h3CustomMul.get(x)).floatValue();
logResult("score3=", s, q3, doc, score3);
assertEquals("new score for custom mul", boost * fieldScore * score1, score3, TEST_SCORE_TOLERANCE_DELTA);
float score4 = ((Float)h4CustomAdd.get(x)).floatValue();
logResult("score4=", s, q4, doc, score4);
assertEquals("new score for custom add", boost * (fieldScore + score1), score4, TEST_SCORE_TOLERANCE_DELTA);
float score5 = ((Float)h5CustomMulAdd.get(x)).floatValue();
logResult("score5=", s, q5, doc, score5);
assertEquals("new score for custom mul add", boost * fieldScore * (score1 + 1), score5, TEST_SCORE_TOLERANCE_DELTA);
}
|
|