// Test that FieldScoreQuery returns docs with expected score. private void DoTestCustomScore(System.String field, FieldScoreQuery.Type tp, double dboost) { float boost = (float)dboost; IndexSearcher s = new IndexSearcher(dir, true); FieldScoreQuery qValSrc = new FieldScoreQuery(field, tp); // a query that would score by the field QueryParser qp = new QueryParser(Util.Version.LUCENE_CURRENT, TEXT_FIELD, anlzr); System.String qtxt = "first aid text"; // 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.Boost = 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.Boost = boost; Log(q3CustomMul); // custom query, that should add the scores of q1 to that of the field CustomScoreQuery q4CustomAdd = new CustomAddQuery(q1, qValSrc); q4CustomAdd.SetStrict(true); q4CustomAdd.Boost = boost; Log(q4CustomAdd); // custom query, that multiplies and adds the field score to that of q1 CustomScoreQuery q5CustomMulAdd = new CustomMulAddQuery(q1, qValSrc, qValSrc); q5CustomMulAdd.SetStrict(true); q5CustomMulAdd.Boost = 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 System.Collections.Hashtable h1 = TopDocsToMap(td1); System.Collections.Hashtable h2CustomNeutral = TopDocsToMap(td2CustomNeutral); System.Collections.Hashtable h3CustomMul = TopDocsToMap(td3CustomMul); System.Collections.Hashtable h4CustomAdd = TopDocsToMap(td4CustomAdd); System.Collections.Hashtable h5CustomMulAdd = TopDocsToMap(td5CustomMulAdd); VerifyResults(boost, s, h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd, q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd); }
// Test that FieldScoreQuery returns docs with expected score. private void DoTestExactScore(System.String field, FieldScoreQuery.Type tp) { IndexSearcher s = new IndexSearcher(dir, true); Query q = new FieldScoreQuery(field, tp); TopDocs td = s.Search(q, null, 1000); Assert.AreEqual(N_DOCS, td.TotalHits, "All docs should be matched!"); ScoreDoc[] sd = td.ScoreDocs; for (int i = 0; i < sd.Length; i++) { float score = sd[i].Score; Log(s.Explain(q, sd[i].Doc)); System.String id = s.IndexReader.Document(sd[i].Doc).Get(ID_FIELD); float expectedScore = ExpectedFieldScore(id); // "ID7" --> 7.0 Assert.AreEqual(expectedScore, score, TEST_SCORE_TOLERANCE_DELTA, "score of " + id + " shuould be " + expectedScore + " != " + score); } }
// Test that FieldScoreQuery returns docs in expected order. private void DoTestRank(System.String field, FieldScoreQuery.Type tp) { IndexSearcher s = new IndexSearcher(dir, true); Query q = new FieldScoreQuery(field, tp); Log("test: " + q); QueryUtils.Check(q, s); ScoreDoc[] h = s.Search(q, null, 1000).ScoreDocs; Assert.AreEqual(N_DOCS, h.Length, "All docs should be matched!"); System.String prevID = "ID" + (N_DOCS + 1); // greater than all ids of docs in this test for (int i = 0; i < h.Length; i++) { System.String resID = s.Doc(h[i].Doc).Get(ID_FIELD); Log(i + ". score=" + h[i].Score + " - " + resID); Log(s.Explain(q, h[i].Doc)); Assert.IsTrue(String.CompareOrdinal(resID, prevID) < 0, "res id " + resID + " should be < prev res id " + prevID); prevID = resID; } }
// Test that values loaded for FieldScoreQuery are cached properly and consumes the proper RAM resources. private void DoTestCaching(System.String field, FieldScoreQuery.Type tp) { // prepare expected array types for comparison System.Collections.Hashtable expectedArrayTypes = new System.Collections.Hashtable(); expectedArrayTypes[FieldScoreQuery.Type.BYTE] = new sbyte[0]; expectedArrayTypes[FieldScoreQuery.Type.SHORT] = new short[0]; expectedArrayTypes[FieldScoreQuery.Type.INT] = new int[0]; expectedArrayTypes[FieldScoreQuery.Type.FLOAT] = new float[0]; IndexSearcher s = new IndexSearcher(dir, true); System.Object[] innerArray = new Object[s.IndexReader.GetSequentialSubReaders().Length]; bool warned = false; // print warning once. for (int i = 0; i < 10; i++) { FieldScoreQuery q = new FieldScoreQuery(field, tp); ScoreDoc[] h = s.Search(q, null, 1000).ScoreDocs; Assert.AreEqual(N_DOCS, h.Length, "All docs should be matched!"); IndexReader[] readers = s.IndexReader.GetSequentialSubReaders(); for (int j = 0; j < readers.Length; j++) { IndexReader reader = readers[j]; try { if (i == 0) { innerArray[j] = q.valSrc.GetValues(reader).InnerArray; Log(i + ". compare: " + innerArray[j].GetType() + " to " + expectedArrayTypes[tp].GetType()); Assert.AreEqual(innerArray[j].GetType(), expectedArrayTypes[tp].GetType(), "field values should be cached in the correct array type!"); } else { Log(i + ". compare: " + innerArray[j] + " to " + q.valSrc.GetValues(reader).InnerArray); Assert.AreSame(innerArray[j], q.valSrc.GetValues(reader).InnerArray, "field values should be cached and reused!"); } } catch (System.NotSupportedException) { if (!warned) { System.Console.Error.WriteLine("WARNING: " + TestName() + " cannot fully test values of " + q); warned = true; } } } } // verify new values are reloaded (not reused) for a new reader s = new IndexSearcher(dir, true); FieldScoreQuery q2 = new FieldScoreQuery(field, tp); ScoreDoc[] h2 = s.Search(q2, null, 1000).ScoreDocs; Assert.AreEqual(N_DOCS, h2.Length, "All docs should be matched!"); IndexReader[] readers2 = s.IndexReader.GetSequentialSubReaders(); for (int j = 0; j < readers2.Length; j++) { IndexReader reader = readers2[j]; try { Log("compare: " + innerArray + " to " + q2.valSrc.GetValues(reader).InnerArray); Assert.AreNotSame(innerArray, q2.valSrc.GetValues(reader).InnerArray, "cached field values should not be reused if reader as changed!"); } catch (System.NotSupportedException) { if (!warned) { System.Console.Error.WriteLine("WARNING: " + TestName() + " cannot fully test values of " + q2); warned = true; } } } }