Skip to content

Commit

Permalink
ToParentBlockJoinQuery Explain Support Score Mode (#12245) (#12283)
Browse files Browse the repository at this point in the history
* `ToParentBlockJoinQuery` Explain Support Score Mode

---------

Co-authored-by: Marcus <marcuseagan@gmail.com>
  • Loading branch information
mkhludnev and MarcusSorealheis authored May 10, 2023
1 parent 8e726f7 commit 37b97a6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
3 changes: 2 additions & 1 deletion lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ New Features

Improvements
---------------------
(No changes)

GITHUB#12245: Add support for Score Mode to `ToParentBlockJoinQuery` explain. (Marcus Eagan via Mikhail Khludnev)

Optimizations
---------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public long cost() {
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");
}
Expand Down Expand Up @@ -392,35 +392,51 @@ private void setScoreAndFreq() throws IOException {
}
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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ public void testSimple() throws Exception {
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);
Expand Down Expand Up @@ -890,13 +889,11 @@ public void testRandom() throws Exception {
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);
Expand Down

0 comments on commit 37b97a6

Please sign in to comment.