Files
mongo/jstests/aggregation/text/text_score_metadata.js
Mihai Andrei eb8bef604c SERVER-99734 Finish moving top level tests in 'jstests/aggregation' into subdirectories (#31578)
GitOrigin-RevId: 2dd0c4d3698dfc4ccb1d7069d214aa6b66f28234
2025-02-03 16:27:34 +00:00

103 lines
3.5 KiB
JavaScript

/**
* Tests that the "text score" metadata (previously known as 'textScore') is accessible by the
* 'score' metadata field in aggregation pipelines.
*
* @tags: [featureFlagRankFusionFull, requires_fcv_81]
*/
const kScoreMetadataArg = "score";
const kTextScoreMetadataArg = "textScore";
const coll = db.foo;
coll.drop();
assert.commandWorked(coll.insertMany([
{_id: 0, x: "test"},
{_id: 1, x: "hello"},
{_id: 2, x: "test test"},
]));
assert.commandWorked(coll.createIndex({x: "text"}));
const textMatchStage = {
$match: {$text: {$search: "test"}}
};
/**
* Helper function to project $textScore in an aggregation, including the option to force the
* projection on the merging shard.
* @param {boolean} forceProjectionOnMerger force the metadata project to be run on the merging
* shard, otherwise allow it to be pushed down.
*/
function runProjectionTest({forceProjectionOnMerger}) {
function buildPipeline(projections) {
let pipeline = [textMatchStage];
if (forceProjectionOnMerger) {
// Add a splitPipeline stage so that the $project will stay on the merging shard and
// exercise dependency analysis there.
pipeline.push({$_internalSplitPipeline: {}});
}
pipeline.push({$project: projections});
return pipeline;
}
const pipelineWithScoreAndTextScore = buildPipeline({
[kTextScoreMetadataArg]: {$meta: kTextScoreMetadataArg},
[kScoreMetadataArg]: {$meta: kScoreMetadataArg}
});
// Generate a document set with both the 'score' and 'textScore' metadata fields projected as
// regular fields.
let results = coll.aggregate(pipelineWithScoreAndTextScore).toArray();
// Ensure both 'score' and 'textScore' are present and equal.
assert.neq(results.length, 0, "results array expected not to be empty");
for (let result of results) {
assert(result.hasOwnProperty(kTextScoreMetadataArg),
`Failed to find ${kTextScoreMetadataArg} in document: ${tojson(result)}`);
assert(result.hasOwnProperty(kScoreMetadataArg),
`Failed to find ${kScoreMetadataArg} in document: ${tojson(result)}`);
assert.eq(result[kTextScoreMetadataArg],
result[kScoreMetadataArg],
"the legacy metadata value '" + kTextScoreMetadataArg +
"' is not equal to the 'score' metadata value");
}
// We should also be able to project $score by itself.
const pipelineWithScoreOnly = buildPipeline({[kScoreMetadataArg]: {$meta: kScoreMetadataArg}});
results = coll.aggregate(pipelineWithScoreOnly).toArray();
assert.neq(results.length, 0, "results array expected not to be empty");
for (let result of results) {
assert(result.hasOwnProperty(kScoreMetadataArg), result);
}
}
(function testProjectScore() {
runProjectionTest({forceProjectionOnMerger: false});
})();
(function testProjectScoreOnMergingShard() {
runProjectionTest({forceProjectionOnMerger: true});
})();
(function testSortOnScore() {
const results =
coll.aggregate([textMatchStage, {$sort: {[kScoreMetadataArg]: {$meta: kScoreMetadataArg}}}])
.toArray();
assert.eq(results, [{_id: 2, x: "test test"}, {_id: 0, x: "test"}]);
})();
(function testGroupOnScore() {
// We should have two distinct entries for two different returned scores.
const results =
coll.aggregate(
[textMatchStage, {$group: {_id: {$meta: kScoreMetadataArg}, count: {$sum: 1}}}])
.toArray();
assert.eq(results.length, 2, results);
})();