Skip to content

ES|QL: Optimize MMR by reducing cache size and lookup#145014

Merged
ioanatia merged 5 commits intoelastic:mainfrom
ioanatia:mmr_optimization
Mar 31, 2026
Merged

ES|QL: Optimize MMR by reducing cache size and lookup#145014
ioanatia merged 5 commits intoelastic:mainfrom
ioanatia:mmr_optimization

Conversation

@ioanatia
Copy link
Copy Markdown
Contributor

closes #140710

for the full explanation - #140710

@ioanatia ioanatia added :Search Relevance/Ranking Scoring, rescoring, rank evaluation. >refactoring Team:Search Relevance Meta label for the Search Relevance team in Elasticsearch labels Mar 26, 2026
@ioanatia ioanatia marked this pull request as ready for review March 30, 2026 13:00
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-search-relevance (Team:Search Relevance)

@ioanatia ioanatia requested a review from markjhoy March 30, 2026 15:21
// compute MMR scores for remaining searchHits
float highestSimilarityScoreToSelected = getHighestSimilarityScoreToSelectedVectors(
selectedDocRanks,
float similarityToLastSelected = getVectorComparisonScore(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I get at what the optimization is here -- you're only comparing the current document to the last selected document, correct? (the original implementation, and the implementation in the paper, computes MMR in respect to all the previously selected documents)...

I think this will work, but it's still unsure in my head if it will produce the most correct results...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still compute MMR wrt all previously selected documents.

We keep an array of the computed max similarity between each doc and the selected set.
Then as we select new diversified docs and we iterate through the remaining docs to find a new candidate:

  • We compute the similarity between the current doc for which we calculate MMR and the doc that was added to the selected docs in the prev iteration.
  • We update the maxSimilarityToSelected[docRank - 1] for the current doc.
  • We compute the MMR score using the maxSimilarityToSelected value for the current doc.

highestScore = similarityScore;
}
}
return highestScore == Float.NEGATIVE_INFINITY ? 0.0f : highestScore;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 minor edge case, just from comparing implementations (not sure if it's a valid one). In the previous code if there was no valid similarity score, we would have 0.0f, but now we will get Float.NEGATIVE_INFINITY, that is if context.getFieldVector() returns null for every selected document.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't actually get to this path, because as we iterate through candidates, we skip those that don't have a vector value:

var thisDocVector = context.getFieldVector(docRank);
if (thisDocVector == null || thisDocVector.size() == 0) {
continue;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right 🤦
Thanks!

Copy link
Copy Markdown
Contributor

@mromaios mromaios left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✅

@ioanatia ioanatia merged commit 7e16024 into elastic:main Mar 31, 2026
35 checks passed
szybia added a commit to szybia/elasticsearch that referenced this pull request Mar 31, 2026
…rics

* upstream/main: (428 commits)
  ESQL: DS: Add inference/RERANK tests (elastic#145229)
  Unmute MMR logical plan test (elastic#145311)
  Do not attempt marking store as corrupted if the check is rejected due to shutdown (elastic#145209)
  feat(tsdb): add pipeline runtime and rename stage interfaces (elastic#145175)
  Fix UnresolvedException on PromQL by(step) grouping (elastic#145307)
  ES|QL: Optimize MMR by reducing cache size and lookup (elastic#145014)
  Prometheus labels/series APIs: support multiple match[] selectors (elastic#145298)
  Move ClientScrollablePaginatedHitSource into Reindex Module (elastic#144100)
  mute test class for elastic#145277
  CPS mode for ViewResolver (elastic#145219)
  [ESQL] Disables GroupedTopNBenchmark temporarily (elastic#145124)
  Make exponential_histogram the default histogram type for HTTP OTLP endpoint (elastic#145065)
  More tests requiring an explicit confidence interval (elastic#145232)
  ES|QL: Adding `USER_AGENT` command (elastic#144384)
  ESQL: enable Generative IT after more fixes (elastic#145112)
  Rework FieldMapper parameter tests to not use merge builders (elastic#145213)
  [ESQL] Fix ORC type support gaps (elastic#145074)
  [Test] Unmute FollowingEngineTests.testProcessOnceOnPrimary (elastic#145192)
  Add PrometheusSeriesRestAction for /_prometheus/api/v1/series endpoint (elastic#144494)
  Prometheus labels API: add rest action (elastic#144952)
  ...
sachinnn99 pushed a commit to sachinnn99/elasticsearch that referenced this pull request Mar 31, 2026
ncordon pushed a commit to ncordon/elasticsearch that referenced this pull request Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>refactoring :Search Relevance/Ranking Scoring, rescoring, rank evaluation. Team:Search Relevance Meta label for the Search Relevance team in Elasticsearch v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MMR: Reduce cache size by reusing previous MMR scores

4 participants