`ToParentBlockJoinQuery` Explain Support Score Mode (#12245)

* `ToParentBlockJoinQuery` Explain Support Score Mode

---------

Co-authored-by: Mikhail Khludnev <mkhl@apache.org>
This commit is contained in:
Marcus 2023-05-10 09:10:37 -07:00 committed by GitHub
parent dcbf7523a1
commit 963ed7ce88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 18 deletions

View File

@ -118,7 +118,8 @@ New Features
Improvements
---------------------
(No changes)
GITHUB#12245: Add support for Score Mode to `ToParentBlockJoinQuery` explain. (Marcus Eagan via Mikhail Khludnev)
Optimizations
---------------------

View File

@ -172,7 +172,7 @@ public class ToParentBlockJoinQuery extends Query {
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
BlockJoinScorer scorer = (BlockJoinScorer) scorer(context);
if (scorer != null && scorer.iterator().advance(doc) == doc) {
return scorer.explain(context, in);
return scorer.explain(context, in, scoreMode);
}
return Explanation.noMatch("Not a match");
}
@ -391,35 +391,51 @@ public class ToParentBlockJoinQuery extends Query {
}
this.score = (float) score;
}
public Explanation explain(LeafReaderContext context, Weight childWeight) throws IOException {
/*
* This instance of Explanation requires three parameters, context, childWeight, and scoreMode.
* The scoreMode parameter considers Avg, Total, Min, Max, and None.
* */
public Explanation explain(LeafReaderContext context, Weight childWeight, ScoreMode scoreMode)
throws IOException {
int prevParentDoc = parentBits.prevSetBit(parentApproximation.docID() - 1);
int start =
context.docBase + prevParentDoc + 1; // +1 b/c prevParentDoc is previous parent doc
int end = context.docBase + parentApproximation.docID() - 1; // -1 b/c parentDoc is parent doc
Explanation bestChild = null;
Explanation worstChild = null;
int matches = 0;
for (int childDoc = start; childDoc <= end; childDoc++) {
Explanation child = childWeight.explain(context, childDoc - context.docBase);
if (child.isMatch()) {
matches++;
if (bestChild == null
|| child.getValue().floatValue() > bestChild.getValue().floatValue()) {
|| child.getValue().doubleValue() > bestChild.getValue().doubleValue()) {
bestChild = child;
}
if (worstChild == null
|| child.getValue().doubleValue() < worstChild.getValue().doubleValue()) {
worstChild = child;
}
}
}
assert matches > 0 : "No matches should be handled before.";
Explanation subExplain = scoreMode == ScoreMode.Min ? worstChild : bestChild;
return Explanation.match(
score(),
String.format(
Locale.ROOT,
"Score based on %d child docs in range from %d to %d, best match:",
matches,
start,
end),
bestChild);
this.score(),
formatScoreExplanation(matches, start, end, scoreMode),
subExplain == null ? Collections.emptyList() : Collections.singleton(subExplain));
}
private String formatScoreExplanation(int matches, int start, int end, ScoreMode scoreMode) {
return String.format(
Locale.ROOT,
"Score based on %d child docs in range from %d to %d, using score mode %s",
matches,
start,
end,
scoreMode);
}
}

View File

@ -277,7 +277,6 @@ public class TestBlockJoin extends LuceneTestCase {
CheckHits.checkHitCollector(random(), fullQuery.build(), "country", s, new int[] {2});
TopDocs topDocs = s.search(fullQuery.build(), 1);
// assertEquals(1, results.totalHitCount);
assertEquals(1, topDocs.totalHits.value);
Document parentDoc = s.storedFields().document(topDocs.scoreDocs[0].doc);
@ -890,13 +889,11 @@ public class TestBlockJoin extends LuceneTestCase {
Explanation explanation = joinS.explain(childJoinQuery, hit.doc);
Document document = joinS.storedFields().document(hit.doc - 1);
int childId = Integer.parseInt(document.get("childID"));
// System.out.println(" hit docID=" + hit.doc + " childId=" + childId + " parentId=" +
// document.get("parentID"));
assertTrue(explanation.isMatch());
assertEquals(hit.score, explanation.getValue().doubleValue(), 0.0f);
Matcher m =
Pattern.compile(
"Score based on ([0-9]+) child docs in range from ([0-9]+) to ([0-9]+), best match:")
"Score based on ([0-9]+) child docs in range from ([0-9]+) to ([0-9]+), using score mode (None|Avg|Min|Max|Total)")
.matcher(explanation.getDescription());
assertTrue("Block Join description not matches", m.matches());
assertTrue("Matched children not positive", Integer.parseInt(m.group(1)) > 0);