Files
mongo/jstests/aggregation/optimization/agg_uses_covered_indices.js
Steve McClure 1ffbc6c2e9 SERVER-109432: Autofix JS var usage to favor let (#40637)
GitOrigin-RevId: 9674b7db36a0f3f650d39c1e3fb2ad6ff2141cfb
2025-08-28 19:21:01 +00:00

85 lines
3.4 KiB
JavaScript

/**
* SERVER-12015 Re-enable covered indices in the aggregation pipeline.
*
* This test executes some simple pipelines and asserts that they have the same results whether or
* not there are indices that could cover the projection part of the query, or provide a
* non-blocking sort.
*/
import {arrayEq} from "jstests/aggregation/extras/utils.js";
const coll = db[jsTestName()];
coll.drop();
const indexSpec = {
a: 1,
b: 1,
};
assert.commandWorked(coll.insert({_id: 0, a: 0, b: 0}));
assert.commandWorked(coll.insert({_id: 1, a: 0, b: 1}));
assert.commandWorked(coll.insert({_id: 2, a: 1, b: 0}));
assert.commandWorked(coll.insert({_id: 3, a: 1, b: 1}));
/**
* Helper to test that for a given pipeline, the same results are returned whether or not an
* index is present. If 'ignoreSortOrder' is present, test for result parity without assuming
* the order of results.
*/
function assertResultsMatch(pipeline, ignoreSortOrder) {
// Add a match stage to ensure index scans are considered for planning (workaround for
// SERVER-20066).
pipeline = [{$match: {a: {$gte: 0}}}].concat(pipeline);
// Once with an index.
assert.commandWorked(coll.createIndex(indexSpec));
let resultsWithIndex = coll.aggregate(pipeline).toArray();
// Again without an index.
assert.commandWorked(coll.dropIndex(indexSpec));
let resultsWithoutIndex = coll.aggregate(pipeline).toArray();
if (ignoreSortOrder) {
assert(
arrayEq(resultsWithIndex, resultsWithoutIndex),
tojson({resultsWithIndex: resultsWithIndex, resultsWithoutIndex: resultsWithoutIndex}),
);
} else {
assert.eq(resultsWithIndex, resultsWithoutIndex);
}
}
// Uncovered $project, no $sort.
const ignoreSortOrder = true;
assertResultsMatch([{$project: {_id: 1, a: 1, b: 1}}], ignoreSortOrder);
// Covered $project, no $sort.
assertResultsMatch([{$project: {_id: 0, a: 1}}], ignoreSortOrder);
assertResultsMatch([{$project: {_id: 0, a: 1, b: 1}}], ignoreSortOrder);
assertResultsMatch([{$project: {_id: 0, a: 1, b: 1, c: {$literal: 1}}}], ignoreSortOrder);
assertResultsMatch([{$project: {_id: 0, a: 1, b: 1}}, {$project: {a: 1}}], ignoreSortOrder);
assertResultsMatch([{$project: {_id: 0, a: 1, b: 1}}, {$group: {_id: null, a: {$sum: "$a"}}}], ignoreSortOrder);
// Non-blocking $sort, uncovered $project.
assertResultsMatch([{$sort: {a: -1, b: -1}}, {$project: {_id: 1, a: 1, b: 1}}]);
assertResultsMatch([{$sort: {a: 1, b: 1}}, {$project: {_id: 1, a: 1, b: 1}}]);
assertResultsMatch(
[{$sort: {a: 1, b: 1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}],
ignoreSortOrder,
);
// Non-blocking $sort, covered $project.
assertResultsMatch([{$sort: {a: -1, b: -1}}, {$project: {_id: 0, a: 1, b: 1}}]);
assertResultsMatch([{$sort: {a: 1, b: 1}}, {$project: {_id: 0, a: 1, b: 1}}]);
assertResultsMatch([{$sort: {a: 1, b: 1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}], ignoreSortOrder);
// Blocking $sort, uncovered $project.
assertResultsMatch([{$sort: {b: 1, a: -1}}, {$project: {_id: 1, a: 1, b: 1}}]);
assertResultsMatch(
[{$sort: {b: 1, a: -1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}],
ignoreSortOrder,
);
// Blocking $sort, covered $project.
assertResultsMatch([{$sort: {b: 1, a: -1}}, {$project: {_id: 0, a: 1, b: 1}}]);
assertResultsMatch([{$sort: {b: 1, a: -1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}], ignoreSortOrder);