mongo/jstests/aggregation/sources/setWindowFields/rank.js
2023-04-26 19:19:19 +00:00

114 lines
3.1 KiB
JavaScript

/**
* Test the rank based window functions.
*/
(function() {
"use strict";
load("jstests/aggregation/extras/utils.js"); // documentEq
const coll = db[jsTestName()];
for (let i = 0; i < 12; i++) {
coll.insert({_id: i, double: Math.floor(i / 2)});
}
let origDocs = coll.find().sort({_id: 1});
function verifyResults(results, valueFunction) {
for (let i = 0; i < results.length; i++) {
const correctDoc = valueFunction(i, Object.assign({}, origDocs[i]));
assert(documentEq(correctDoc, results[i]),
"Got: " + tojson(results[i]) + "\nExpected: " + tojson(correctDoc) +
"\n at position " + i + "\n");
}
}
function runRankBasedAccumulator(sortByField, exprField) {
return coll
.aggregate([{
$setWindowFields: {sortBy: sortByField, output: {rank: exprField}},
}])
.toArray();
}
// Rank based accumulators don't take windows.
assert.commandFailedWithCode(coll.runCommand({
aggregate: coll.getName(),
pipeline: [{
$setWindowFields: {
sortBy: {_id: 1},
output: {rank: {$rank: {}, window: []}},
}
}],
cursor: {}
}),
5371601);
// Rank based accumulators don't take arguments.
assert.commandFailedWithCode(coll.runCommand({
aggregate: coll.getName(),
pipeline: [{
$setWindowFields: {
sortBy: {_id: 1},
output: {rank: {$rank: "$_id"}},
}
}],
cursor: {}
}),
5371603);
// Rank based accumulators must have a sortBy.
assert.commandFailedWithCode(coll.runCommand({
aggregate: coll.getName(),
pipeline: [{
$setWindowFields: {
output: {rank: {$rank: {}}},
}
}],
cursor: {}
}),
5371602);
// Rank based accumulators don't take windows.
assert.commandFailedWithCode(coll.runCommand({
aggregate: coll.getName(),
pipeline: [{
$setWindowFields: {
sortBy: {_id: 1},
output: {rank: {$rank: {}, window: {documents: [-1, 1]}}},
}
}],
cursor: {}
}),
5371601);
// Check results with no ties
let result = runRankBasedAccumulator({_id: 1}, {$rank: {}});
function noTieFunc(num, baseObj) {
baseObj.rank = num + 1;
return baseObj;
}
verifyResults(result, noTieFunc);
result = runRankBasedAccumulator({_id: 1}, {$denseRank: {}});
verifyResults(result, noTieFunc);
result = runRankBasedAccumulator({_id: 1}, {$documentNumber: {}});
verifyResults(result, noTieFunc);
// Check results with ties
origDocs = coll.find().sort({double: 1});
result = runRankBasedAccumulator({double: 1}, {$rank: {}});
verifyResults(result, function(num, baseObj) {
if (num % 2 == 0) {
baseObj.rank = num + 1;
} else {
baseObj.rank = num;
}
return baseObj;
});
result = runRankBasedAccumulator({double: 1}, {$denseRank: {}});
verifyResults(result, function(num, baseObj) {
baseObj.rank = Math.floor(num / 2) + 1;
return baseObj;
});
result = runRankBasedAccumulator({double: 1}, {$documentNumber: {}});
verifyResults(result, noTieFunc);
})();