/** * 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); })();