JAVA-5990 Hybrid Search Score Fusion - #2024
Conversation
There was a problem hiding this comment.
Pull request overview
Adds Java and Scala driver support for MongoDB 8.2’s $scoreFusion aggregation stage (hybrid search score fusion), including new model/builder types and pipeline stage factory methods, plus driver-core unit/functional coverage.
Changes:
- Introduces new
com.mongodb.client.modeltypes for$scoreFusion:FusionPipeline,ScoreNormalization,ScoreFusionCombination,WeightedScoreFusionCombination, andScoreFusionOptions. - Adds
Aggregates.scoreFusion(...)overloads and BSON rendering implementation indriver-core. - Adds driver-core unit + functional tests for construction, rendering, and basic server-side execution; adds Scala API wrappers (type aliases + companion objects +
Aggregates.scoreFusion), but no Scala tests.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| driver-scala/src/main/scala/org/mongodb/scala/model/ScoreNormalization.scala | Scala companion object delegating to Java ScoreNormalization factories. |
| driver-scala/src/main/scala/org/mongodb/scala/model/ScoreFusionOptions.scala | Scala companion object delegating to Java ScoreFusionOptions.scoreFusionOptions(). |
| driver-scala/src/main/scala/org/mongodb/scala/model/ScoreFusionCombination.scala | Scala companion object delegating to Java combination factories (weighted/expression). |
| driver-scala/src/main/scala/org/mongodb/scala/model/package.scala | Adds Scala type aliases + FusionPipeline companion for $scoreFusion API surface. |
| driver-scala/src/main/scala/org/mongodb/scala/model/Aggregates.scala | Adds Scala Aggregates.scoreFusion overloads delegating to Java driver-core. |
| driver-core/src/main/com/mongodb/client/model/FusionPipeline.java | New value type representing a named input pipeline with validation. |
| driver-core/src/main/com/mongodb/client/model/ScoreNormalization.java | New public API for score normalization selection/serialization. |
| driver-core/src/main/com/mongodb/client/model/ScoreNormalizationBson.java | Internal ScoreNormalization implementation backed by a BsonValue. |
| driver-core/src/main/com/mongodb/client/model/ScoreFusionCombination.java | New public API for combination strategies (weighted/expression). |
| driver-core/src/main/com/mongodb/client/model/WeightedScoreFusionCombination.java | New public subtype enabling .avg() on weighted combinations. |
| driver-core/src/main/com/mongodb/client/model/ScoreFusionOptions.java | New public options API for $scoreFusion (combination, scoreDetails, option). |
| driver-core/src/main/com/mongodb/client/model/ScoreFusionConstructibleBson.java | Internal constructible BSON implementation for options/combination builders. |
| driver-core/src/main/com/mongodb/client/model/Aggregates.java | Adds $scoreFusion stage factory methods + BSON rendering implementation. |
| driver-core/src/test/unit/com/mongodb/client/model/AggregatesSpecification.groovy | Adds unit specs for new builders + BSON rendering + argument validation. |
| driver-core/src/test/functional/com/mongodb/client/model/search/AggregatesSearchIntegrationTest.java | Adds integration coverage for $scoreFusion with $search + $vectorSearch. |
| driver-core/src/test/functional/com/mongodb/client/model/AggregatesTest.java | Adds functional tests exercising normalization/combination/scoreDetails behaviors. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines, | ||
| * normalizing and combining the scores they produce. | ||
| * | ||
| * @param pipelines the non-empty input pipelines with unique names | ||
| * @param normalization the way in which the scores produced by the input pipelines are normalized | ||
| * @return the `\$scoreFusion` pipeline stage | ||
| * @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]] | ||
| * @note Requires MongoDB 8.2 or greater | ||
| * @since 5.10 | ||
| */ | ||
| def scoreFusion(pipelines: Seq[FusionPipeline], normalization: ScoreNormalization): Bson = | ||
| JAggregates.scoreFusion(pipelines.asJava, normalization) |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
driver-scala/src/main/scala/org/mongodb/scala/model/Aggregates.scala:210
- The Scala wrapper adds new public
Aggregates.scoreFusionoverloads, but there is no corresponding Scala unit test to validate the rendered BSON (unlike other aggregation stages indriver-scala/src/test/scala/org/mongodb/scala/model/AggregatesSpec.scala). Please add a Scala-spec test that exercisesFusionPipeline,ScoreNormalization,ScoreFusionOptions/Combination, and asserts the produced$scoreFusiondocument shape.
/**
* Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines,
* normalizing and combining the scores they produce.
*
* @param pipelines the non-empty input pipelines with unique names
* @param normalization the way in which the scores produced by the input pipelines are normalized
* @return the `\$scoreFusion` pipeline stage
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]]
* @note Requires MongoDB 8.2 or greater
* @since 5.10
*/
def scoreFusion(pipelines: Seq[FusionPipeline], normalization: ScoreNormalization): Bson =
JAggregates.scoreFusion(pipelines.asJava, normalization)
/**
* Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines,
* normalizing and combining the scores they produce.
*
* @param pipelines the non-empty input pipelines with unique names
* @param normalization the way in which the scores produced by the input pipelines are normalized
* @param options optional `\$scoreFusion` pipeline stage fields
* @return the `\$scoreFusion` pipeline stage
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]]
* @note Requires MongoDB 8.2 or greater
* @since 5.10
*/
def scoreFusion(
pipelines: Seq[FusionPipeline],
normalization: ScoreNormalization,
options: ScoreFusionOptions
): Bson =
JAggregates.scoreFusion(pipelines.asJava, normalization, options)
Temporarily duplicates the ScoreNormalization enum from PR mongodb#2023 so both branches compile independently; once JAVA-6202 merges, the duplicate is dropped in favor of theirs.
| import org.bson.BsonDocument | ||
| import org.bson.BsonInt32 | ||
| import org.bson.BsonString | ||
| import org.bson.Document |
| /** | ||
| * Normalization methods for the `\$score` pipeline stage. | ||
| * | ||
| * @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/score/ \$score]] | ||
| * @note Requires MongoDB 8.2 or greater | ||
| * @since 5.10 | ||
| */ |
| /** | ||
| * Normalization methods for the {@code $score} pipeline stage. | ||
| * | ||
| * @mongodb.driver.manual reference/operator/aggregation/score/ $score | ||
| * @mongodb.server.release 8.2 | ||
| * @since 5.10 | ||
| */ |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
driver-core/src/test/unit/com/mongodb/client/model/AggregatesSpecification.groovy:26
- Unused import
org.bson.BsonString(only appears in the import list). Removing it avoids unused-import warnings/failures under stricter checks.
import org.bson.BsonDocument
import org.bson.BsonInt32
import org.bson.BsonString
import org.bson.Document
driver-scala/src/main/scala/org/mongodb/scala/model/Aggregates.scala:210
- Scala API surface was extended with
Aggregates.scoreFusion(...), but there are no Scala-side tests validating BSON rendering/behavior (e.g., indriver-scala's existingAggregatesSpec). Please add Scala tests for the new stage and related model helpers to prevent regressions.
/**
* Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines,
* normalizing and combining the scores they produce.
*
* @param pipelines the non-empty input pipelines with unique names
* @param normalization the way in which the scores produced by the input pipelines are normalized
* @return the `\$scoreFusion` pipeline stage
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]]
* @note Requires MongoDB 8.2 or greater
* @since 5.10
*/
def scoreFusion(pipelines: Seq[FusionPipeline], normalization: ScoreNormalization): Bson =
JAggregates.scoreFusion(pipelines.asJava, normalization)
/**
* Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines,
* normalizing and combining the scores they produce.
*
* @param pipelines the non-empty input pipelines with unique names
* @param normalization the way in which the scores produced by the input pipelines are normalized
* @param options optional `\$scoreFusion` pipeline stage fields
* @return the `\$scoreFusion` pipeline stage
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]]
* @note Requires MongoDB 8.2 or greater
* @since 5.10
*/
def scoreFusion(
pipelines: Seq[FusionPipeline],
normalization: ScoreNormalization,
options: ScoreFusionOptions
): Bson =
JAggregates.scoreFusion(pipelines.asJava, normalization, options)
driver-core/src/main/com/mongodb/client/model/ScoreFusionConstructibleBson.java:36
ScoreFusionConstructibleBsonhas an unusedorg.bson.BsonDocumentimport, which will fail Java compilation. Since the class referencesBsonDocumentonly in Javadoc, remove the import and fully-qualify the Javadoc link instead.
import com.mongodb.annotations.Immutable;
import com.mongodb.internal.client.model.AbstractConstructibleBson;
import org.bson.BsonBoolean;
import org.bson.BsonDocument;
import org.bson.BsonString;
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
driver-core/src/test/unit/com/mongodb/client/model/AggregatesSpecification.groovy:26
- Unused import
org.bson.BsonStringis present but not referenced anywhere in this spec; it should be removed to keep the import list minimal.
import org.bson.BsonDocument
import org.bson.BsonInt32
import org.bson.BsonString
import org.bson.Document
driver-scala/src/main/scala/org/mongodb/scala/model/Aggregates.scala:210
- The Scala API adds new $scoreFusion builders/types, but there are no Scala unit tests verifying the rendered BSON (similar to the existing $vectorSearch/$rerank rendering tests in
driver-scala/src/test/scala/org/mongodb/scala/model/AggregatesSpec.scala). Please add a Scala test that exercisesAggregates.scoreFusion,FusionPipeline.apply,ScoreNormalization, andScoreFusionOptions.scoreFusionOptions()to catch wrapper/codec regressions.
/**
* Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines,
* normalizing and combining the scores they produce.
*
* @param pipelines the non-empty input pipelines with unique names
* @param normalization the way in which the scores produced by the input pipelines are normalized
* @return the `\$scoreFusion` pipeline stage
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]]
* @note Requires MongoDB 8.2 or greater
* @since 5.10
*/
def scoreFusion(pipelines: Seq[FusionPipeline], normalization: ScoreNormalization): Bson =
JAggregates.scoreFusion(pipelines.asJava, normalization)
/**
* Creates a `\$scoreFusion` pipeline stage, which combines the results of the given input pipelines,
* normalizing and combining the scores they produce.
*
* @param pipelines the non-empty input pipelines with unique names
* @param normalization the way in which the scores produced by the input pipelines are normalized
* @param options optional `\$scoreFusion` pipeline stage fields
* @return the `\$scoreFusion` pipeline stage
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/ \$scoreFusion]]
* @note Requires MongoDB 8.2 or greater
* @since 5.10
*/
def scoreFusion(
pipelines: Seq[FusionPipeline],
normalization: ScoreNormalization,
options: ScoreFusionOptions
): Bson =
JAggregates.scoreFusion(pipelines.asJava, normalization, options)
| @@ -0,0 +1,45 @@ | |||
| /* | |||
| * Copyright 2008-present MongoDB, Inc. | |||
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
driver-core/src/test/unit/com/mongodb/client/model/AggregatesSpecification.groovy:26
- Unused import
org.bson.BsonString(no references in this specification). Unused imports can break the build under strict compilation/lint settings.
import org.bson.BsonDocument
import org.bson.BsonInt32
import org.bson.BsonString
import org.bson.Document
driver-core/src/main/com/mongodb/client/model/ScoreFusionConstructibleBson.java:33
org.bson.BsonDocumentis imported but only referenced in Javadoc; in Java this is an unused import and will fail compilation. Remove the import and fully-qualify the Javadoc link instead.
import org.bson.BsonBoolean;
import org.bson.BsonDocument;
import org.bson.BsonString;
driver-core/src/test/functional/com/mongodb/client/model/AggregatesTest.java:64
- Unused static import
java.util.Collections.singletonList(the file usesCollections.singletonListinstead). In Java, unused imports are compilation errors.
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
| @@ -0,0 +1,55 @@ | |||
| /* | |||
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
driver-core/src/test/functional/com/mongodb/client/model/search/AggregatesSearchIntegrationTest.java:376
- The score/value comparison uses exact double equality, which can be flaky if the server returns numerically equivalent values with slightly different floating-point representations. This file already uses a delta for score comparisons (see Asserters.score), so it would be more consistent and robust to do the same here.
BsonDocument scoreDetails = result.getDocument("scoreDetails");
assertEquals(score, scoreDetails.getNumber("value").doubleValue(), msgSupplier(pipeline));
assertEquals("sigmoid", scoreDetails.getString("normalization").getValue(), msgSupplier(pipeline));
https://jira.mongodb.org/browse/JAVA-5990