use of org.apache.lucene.search.Explanation in project lucene-solr by apache.
the class TestJoinUtil method testOrdinalsJoinExplainNoMatches.
public void testOrdinalsJoinExplainNoMatches() throws Exception {
final String idField = "id";
final String productIdField = "productId";
// A field indicating to what type a document belongs, which is then used to distinques between documents during joining.
final String typeField = "type";
// A single sorted doc values field that holds the join values for all document types.
// Typically during indexing a schema will automatically create this field with the values
final String joinField = idField + productIdField;
Directory dir = newDirectory();
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random())).setMergePolicy(NoMergePolicy.INSTANCE));
// 0
Document doc = new Document();
doc.add(new TextField(idField, "1", Field.Store.NO));
doc.add(new TextField(typeField, "product", Field.Store.NO));
doc.add(new TextField("description", "random text", Field.Store.NO));
doc.add(new TextField("name", "name1", Field.Store.NO));
doc.add(new SortedDocValuesField(joinField, new BytesRef("1")));
w.addDocument(doc);
// 1
doc = new Document();
doc.add(new TextField(idField, "2", Field.Store.NO));
doc.add(new TextField(typeField, "product", Field.Store.NO));
doc.add(new TextField("description", "random text", Field.Store.NO));
doc.add(new TextField("name", "name2", Field.Store.NO));
doc.add(new SortedDocValuesField(joinField, new BytesRef("2")));
w.addDocument(doc);
// 2
doc = new Document();
doc.add(new TextField(productIdField, "1", Field.Store.NO));
doc.add(new TextField(typeField, "price", Field.Store.NO));
doc.add(new TextField("price", "10.0", Field.Store.NO));
doc.add(new SortedDocValuesField(joinField, new BytesRef("1")));
w.addDocument(doc);
// 3
doc = new Document();
doc.add(new TextField(productIdField, "2", Field.Store.NO));
doc.add(new TextField(typeField, "price", Field.Store.NO));
doc.add(new TextField("price", "20.0", Field.Store.NO));
doc.add(new SortedDocValuesField(joinField, new BytesRef("1")));
w.addDocument(doc);
if (random().nextBoolean()) {
w.flush();
}
// 4
doc = new Document();
doc.add(new TextField(productIdField, "3", Field.Store.NO));
doc.add(new TextField(typeField, "price", Field.Store.NO));
doc.add(new TextField("price", "5.0", Field.Store.NO));
doc.add(new SortedDocValuesField(joinField, new BytesRef("2")));
w.addDocument(doc);
// 5
doc = new Document();
doc.add(new TextField("field", "value", Field.Store.NO));
w.addDocument(doc);
IndexReader r = DirectoryReader.open(w);
IndexSearcher indexSearcher = new IndexSearcher(r);
SortedDocValues[] values = new SortedDocValues[r.leaves().size()];
for (int i = 0; i < values.length; i++) {
LeafReader leafReader = r.leaves().get(i).reader();
values[i] = DocValues.getSorted(leafReader, joinField);
}
MultiDocValues.OrdinalMap ordinalMap = MultiDocValues.OrdinalMap.build(null, values, PackedInts.DEFAULT);
Query toQuery = new TermQuery(new Term("price", "5.0"));
Query fromQuery = new TermQuery(new Term("name", "name2"));
for (ScoreMode scoreMode : ScoreMode.values()) {
Query joinQuery = JoinUtil.createJoinQuery(joinField, fromQuery, toQuery, indexSearcher, scoreMode, ordinalMap);
TopDocs result = indexSearcher.search(joinQuery, 10);
assertEquals(1, result.totalHits);
// doc with price: 5.0
assertEquals(4, result.scoreDocs[0].doc);
Explanation explanation = indexSearcher.explain(joinQuery, 4);
assertTrue(explanation.isMatch());
assertEquals(explanation.getDescription(), "A match, join value 2");
explanation = indexSearcher.explain(joinQuery, 3);
assertFalse(explanation.isMatch());
assertEquals(explanation.getDescription(), "Not a match, join value 1");
explanation = indexSearcher.explain(joinQuery, 5);
assertFalse(explanation.isMatch());
assertEquals(explanation.getDescription(), "Not a match");
}
w.close();
indexSearcher.getIndexReader().close();
dir.close();
}
use of org.apache.lucene.search.Explanation in project lucene-solr by apache.
the class TestJoinUtil method assertTopDocs.
private void assertTopDocs(TopDocs expectedTopDocs, TopDocs actualTopDocs, ScoreMode scoreMode, IndexSearcher indexSearcher, Query joinQuery) throws IOException {
assertEquals(expectedTopDocs.totalHits, actualTopDocs.totalHits);
assertEquals(expectedTopDocs.scoreDocs.length, actualTopDocs.scoreDocs.length);
if (scoreMode == ScoreMode.None) {
return;
}
if (VERBOSE) {
for (int i = 0; i < expectedTopDocs.scoreDocs.length; i++) {
System.out.printf(Locale.ENGLISH, "Expected doc: %d | Actual doc: %d\n", expectedTopDocs.scoreDocs[i].doc, actualTopDocs.scoreDocs[i].doc);
System.out.printf(Locale.ENGLISH, "Expected score: %f | Actual score: %f\n", expectedTopDocs.scoreDocs[i].score, actualTopDocs.scoreDocs[i].score);
}
}
assertEquals(expectedTopDocs.getMaxScore(), actualTopDocs.getMaxScore(), 0.0f);
for (int i = 0; i < expectedTopDocs.scoreDocs.length; i++) {
assertEquals(expectedTopDocs.scoreDocs[i].doc, actualTopDocs.scoreDocs[i].doc);
assertEquals(expectedTopDocs.scoreDocs[i].score, actualTopDocs.scoreDocs[i].score, 0.0f);
Explanation explanation = indexSearcher.explain(joinQuery, expectedTopDocs.scoreDocs[i].doc);
assertEquals(expectedTopDocs.scoreDocs[i].score, explanation.getValue(), 0.0f);
}
}
use of org.apache.lucene.search.Explanation in project lucene-solr by apache.
the class TestFunctionRangeQuery method testExplainMultiValued.
@Test
public void testExplainMultiValued() throws IOException {
Query rangeQuery = new FunctionRangeQuery(INT_MV_MIN_VALUESOURCE, 2, 2, true, true);
ScoreDoc[] scoreDocs = indexSearcher.search(rangeQuery, N_DOCS).scoreDocs;
Explanation explain = indexSearcher.explain(rangeQuery, scoreDocs[0].doc);
// Just validate it looks reasonable
assertEquals("2.0 = frange(int(" + INT_FIELD_MV_MIN + ",MIN)):[2 TO 2]\n" + " 2.0 = int(" + INT_FIELD_MV_MIN + ",MIN)=2\n", explain.toString());
}
use of org.apache.lucene.search.Explanation in project lucene-solr by apache.
the class TestFunctionScoreExplanations method testExplanationsIncludingScore.
public void testExplanationsIncludingScore() throws Exception {
DoubleValuesSource scores = DoubleValuesSource.function(DoubleValuesSource.SCORES, "v * 2", v -> v * 2);
Query q = new TermQuery(new Term(FIELD, "w1"));
FunctionScoreQuery csq = new FunctionScoreQuery(q, scores);
qtest(csq, new int[] { 0, 1, 2, 3 });
Explanation e1 = searcher.explain(q, 0);
Explanation e = searcher.explain(csq, 0);
assertEquals(e.getDetails().length, 2);
assertEquals(e1.getValue() * 2, e.getValue(), 0.00001);
}
use of org.apache.lucene.search.Explanation in project lucene-solr by apache.
the class MultipleAdditiveTreesModel method explain.
// /////////////////////////////////////////
// produces a string that looks like:
// 40.0 = multipleadditivetreesmodel [ org.apache.solr.ltr.model.MultipleAdditiveTreesModel ]
// model applied to
// features, sum of:
// 50.0 = tree 0 | 'matchedTitle':1.0 > 0.500001, Go Right |
// 'this_feature_doesnt_exist' does not
// exist in FV, Go Left | val: 50.0
// -10.0 = tree 1 | val: -10.0
@Override
public Explanation explain(LeafReaderContext context, int doc, float finalScore, List<Explanation> featureExplanations) {
final float[] fv = new float[featureExplanations.size()];
int index = 0;
for (final Explanation featureExplain : featureExplanations) {
fv[index] = featureExplain.getValue();
index++;
}
final List<Explanation> details = new ArrayList<>();
index = 0;
for (final RegressionTree t : trees) {
final float score = t.score(fv);
final Explanation p = Explanation.match(score, "tree " + index + " | " + t.explain(fv));
details.add(p);
index++;
}
return Explanation.match(finalScore, toString() + " model applied to features, sum of:", details);
}
Aggregations