Skip to content

JAVA-5990 Hybrid Search Score Fusion - #2024

Open
nhachicha wants to merge 24 commits into
mongodb:mainfrom
nhachicha:nh/hybrid_search
Open

JAVA-5990 Hybrid Search Score Fusion#2024
nhachicha wants to merge 24 commits into
mongodb:mainfrom
nhachicha:nh/hybrid_search

Conversation

@nhachicha

Copy link
Copy Markdown
Collaborator

Copilot AI left a comment

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.

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.model types for $scoreFusion: FusionPipeline, ScoreNormalization, ScoreFusionCombination, WeightedScoreFusionCombination, and ScoreFusionOptions.
  • Adds Aggregates.scoreFusion(...) overloads and BSON rendering implementation in driver-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.

Comment on lines +179 to +191
/**
* 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)

Copilot AI left a comment

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.

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.scoreFusion overloads, but there is no corresponding Scala unit test to validate the rendered BSON (unlike other aggregation stages in driver-scala/src/test/scala/org/mongodb/scala/model/AggregatesSpec.scala). Please add a Scala-spec test that exercises FusionPipeline, ScoreNormalization, ScoreFusionOptions/Combination, and asserts the produced $scoreFusion document 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.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comment on lines 23 to 26
import org.bson.BsonDocument
import org.bson.BsonInt32
import org.bson.BsonString
import org.bson.Document
Comment on lines +21 to +27
/**
* 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
*/
Comment on lines +19 to +25
/**
* Normalization methods for the {@code $score} pipeline stage.
*
* @mongodb.driver.manual reference/operator/aggregation/score/ $score
* @mongodb.server.release 8.2
* @since 5.10
*/

Copilot AI left a comment

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.

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., in driver-scala's existing AggregatesSpec). 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

  • ScoreFusionConstructibleBson has an unused org.bson.BsonDocument import, which will fail Java compilation. Since the class references BsonDocument only 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;

@nhachicha nhachicha mentioned this pull request Jul 28, 2026

Copilot AI left a comment

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.

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.BsonString is 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 exercises Aggregates.scoreFusion, FusionPipeline.apply, ScoreNormalization, and ScoreFusionOptions.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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Note this is a duplicate of #2023 and will be removed when #2023 is merged

Copilot AI left a comment

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.

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.BsonDocument is 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 uses Collections.singletonList instead). 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 @@
/*

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Note this is a duplicate of #2023 and will be removed when #2023 is merged

@nhachicha
nhachicha requested a review from rozza July 28, 2026 14:34
@nhachicha
nhachicha marked this pull request as ready for review July 28, 2026 14:34
@nhachicha
nhachicha requested a review from a team as a code owner July 28, 2026 14:34

Copilot AI left a comment

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.

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));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants