From 32064f88ed311247af2b707a3560e57543aebcc8 Mon Sep 17 00:00:00 2001 From: Mihai Andrei Date: Fri, 5 Nov 2021 02:49:23 +0000 Subject: SERVER-59133 Change 'output' parameter to 'input' in syntax for $firstN/$lastN/$minN/$maxN --- jstests/aggregation/accumulators/first_n_last_n.js | 17 +++++---- jstests/aggregation/accumulators/min_n_max_n.js | 20 +++++------ jstests/aggregation/expressions/n_expressions.js | 20 +++++------ .../sources/setWindowFields/n_accumulators.js | 18 +++++----- src/mongo/db/pipeline/accumulator_multi.cpp | 20 +++++------ src/mongo/db/pipeline/accumulator_multi.h | 13 ++++--- src/mongo/db/pipeline/expression_test.cpp | 40 +++++++++++----------- 7 files changed, 76 insertions(+), 72 deletions(-) diff --git a/jstests/aggregation/accumulators/first_n_last_n.js b/jstests/aggregation/accumulators/first_n_last_n.js index 201f35c8491..fd9a34ea24e 100644 --- a/jstests/aggregation/accumulators/first_n_last_n.js +++ b/jstests/aggregation/accumulators/first_n_last_n.js @@ -17,7 +17,7 @@ if (!isExactTopNEnabled) { // rest of the test. assert.commandFailedWithCode(coll.runCommand("aggregate", { pipeline: - [{$group: {_id: {'st': '$state'}, firstValues: {$firstN: {output: '$sales', n: 2}}}}], + [{$group: {_id: {'st': '$state'}, firstValues: {$firstN: {input: '$sales', n: 2}}}}], cursor: {} }), 15952); @@ -43,7 +43,7 @@ assert.commandWorked(coll.insert(docs)); const actualFirstNResults = coll.aggregate([ {$sort: {_id: 1}}, - {$group: {_id: '$state', sales: {$firstN: {output: "$sales", n: n}}}}, + {$group: {_id: '$state', sales: {$firstN: {input: "$sales", n: n}}}}, ]) .toArray(); @@ -53,7 +53,7 @@ const expectedFirstNResults = const actualLastNResults = coll.aggregate([ {$sort: {_id: 1}}, - {$group: {_id: '$state', sales: {$lastN: {output: "$sales", n: n}}}}, + {$group: {_id: '$state', sales: {$lastN: {input: "$sales", n: n}}}}, ]) .toArray(); @@ -71,20 +71,19 @@ arrayEq(expectedLastNResults, actualLastNResults); // Reject non-integral values of n. assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: - [{$group: {_id: {'st': '$state'}, sales: {$firstN: {output: '$sales', n: 'string'}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, sales: {$firstN: {input: '$sales', n: 'string'}}}}], cursor: {} }), 5787902); assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, sales: {$firstN: {output: '$sales', n: 3.2}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, sales: {$firstN: {input: '$sales', n: 3.2}}}}], cursor: {} }), 5787903); assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$firstN: {output: '$sales', n: -1}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$firstN: {input: '$sales', n: -1}}}}], cursor: {} }), 5787908); @@ -96,7 +95,7 @@ assert.commandFailedWithCode(coll.runCommand("aggregate", { pipeline: [{ $group: { _id: {'st': '$state'}, - sales: {$firstN: {output: '$sales', n: 2, randomField: "randomArg"}} + sales: {$firstN: {input: '$sales', n: 2, randomField: "randomArg"}} } }], cursor: {} @@ -105,7 +104,7 @@ assert.commandFailedWithCode(coll.runCommand("aggregate", { // Missing arguments. assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, sales: {$firstN: {output: '$sales'}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, sales: {$firstN: {input: '$sales'}}}}], cursor: {} }), 5787906); diff --git a/jstests/aggregation/accumulators/min_n_max_n.js b/jstests/aggregation/accumulators/min_n_max_n.js index 62f12f76df2..a493fb2bf02 100644 --- a/jstests/aggregation/accumulators/min_n_max_n.js +++ b/jstests/aggregation/accumulators/min_n_max_n.js @@ -14,7 +14,7 @@ if (!isExactTopNEnabled) { // Verify that $minN/$maxN cannot be used if the feature flag is set to false and ignore the // rest of the test. assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {output: '$sales', n: 2}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {input: '$sales', n: 2}}}}], cursor: {} }), 15952); @@ -56,7 +56,7 @@ assert.commandWorked(coll.insert(docs)); // expected groups (we cannot perform unordered comparison because order matters for $minN/$maxN). const actualMinNResults = coll.aggregate([ - {$group: {_id: '$state', minSales: {$minN: {output: '$sales', n: n}}}}, + {$group: {_id: '$state', minSales: {$minN: {input: '$sales', n: n}}}}, {$sort: {_id: 1}} ]) .toArray(); @@ -64,7 +64,7 @@ assert.eq(expectedMinNResults, actualMinNResults); const actualMaxNResults = coll.aggregate([ - {$group: {_id: '$state', maxSales: {$maxN: {output: '$sales', n: n}}}}, + {$group: {_id: '$state', maxSales: {$maxN: {input: '$sales', n: n}}}}, {$sort: {_id: 1}} ]) .toArray(); @@ -76,7 +76,7 @@ const groupKeyNExpr = { }; const dynamicMinNResults = coll.aggregate([{ - $group: {_id: {'st': '$state'}, minSales: {$minN: {output: '$sales', n: groupKeyNExpr}}} + $group: {_id: {'st': '$state'}, minSales: {$minN: {input: '$sales', n: groupKeyNExpr}}} }]) .toArray(); @@ -103,7 +103,7 @@ assert.commandFailedWithCode(coll.runCommand("aggregate", { $bucketAuto: { groupBy: "$state", buckets: 2, - output: {minSales: {$minN: {output: '$sales', n: groupKeyNExpr}}} + output: {minSales: {$minN: {input: '$sales', n: groupKeyNExpr}}} } }], cursor: {} @@ -113,19 +113,19 @@ assert.commandFailedWithCode(coll.runCommand("aggregate", { // Reject non-integral/negative values of n. assert.commandFailedWithCode(coll.runCommand("aggregate", { pipeline: - [{$group: {_id: {'st': '$state'}, minSales: {$minN: {output: '$sales', n: 'string'}}}}], + [{$group: {_id: {'st': '$state'}, minSales: {$minN: {input: '$sales', n: 'string'}}}}], cursor: {} }), 5787902); assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {output: '$sales', n: 3.2}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {input: '$sales', n: 3.2}}}}], cursor: {} }), 5787903); assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {output: '$sales', n: -1}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {input: '$sales', n: -1}}}}], cursor: {} }), 5787908); @@ -134,7 +134,7 @@ assert.commandFailedWithCode(coll.runCommand("aggregate", { // Missing arguments. assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {output: '$sales'}}}}], + pipeline: [{$group: {_id: {'st': '$state'}, minSales: {$minN: {input: '$sales'}}}}], cursor: {} }), 5787906); @@ -150,7 +150,7 @@ assert.commandFailedWithCode(coll.runCommand("aggregate", { pipeline: [{ $group: { _id: {'st': '$state'}, - minSales: {$minN: {output: '$sales', n: 2, randomField: "randomArg"}} + minSales: {$minN: {input: '$sales', n: 2, randomField: "randomArg"}} } }], cursor: {} diff --git a/jstests/aggregation/expressions/n_expressions.js b/jstests/aggregation/expressions/n_expressions.js index 7e79845608d..60ea494b81d 100644 --- a/jstests/aggregation/expressions/n_expressions.js +++ b/jstests/aggregation/expressions/n_expressions.js @@ -17,11 +17,11 @@ const isExactTopNEnabled = db.adminCommand({getParameter: 1, featureFlagExactTop if (!isExactTopNEnabled) { // Verify that $minN/$maxN cannot be used if the feature flag is set to false and ignore the // rest of the test. - assert.commandFailedWithCode(coll.runCommand("aggregate", { - pipeline: [{$project: {output: {'$minN': {n: 3, output: [3, 1, 2, 3]}}}}], - cursor: {} - }), - 31325); + assert.commandFailedWithCode( + coll.runCommand( + "aggregate", + {pipeline: [{$project: {output: {'$minN': {n: 3, input: [3, 1, 2, 3]}}}}], cursor: {}}), + 31325); return; } @@ -33,14 +33,14 @@ function testExpr(expression, expected) { expected); } -let args = {n: 3, output: [5, 4, 3, 2, 1]}; +let args = {n: 3, input: [5, 4, 3, 2, 1]}; testExpr({$minN: args}, [1, 2, 3]); testExpr({$maxN: args}, [5, 4, 3]); testExpr({$firstN: args}, [5, 4, 3]); testExpr({$lastN: args}, [3, 2, 1]); args = { n: 3, - output: [null, 2, null, 1] + input: [null, 2, null, 1] }; testExpr({$minN: args}, [1, 2]); testExpr({$maxN: args}, [2, 1]); @@ -48,7 +48,7 @@ testExpr({$firstN: args}, [null, 2, null]); testExpr({$lastN: args}, [2, null, 1]); args = { n: 3, - output: "$a" + input: "$a" }; testExpr({$minN: args}, [1, 2, 3]); testExpr({$maxN: args}, [9, 7, 5]); @@ -56,7 +56,7 @@ testExpr({$firstN: args}, [1, 2, 3]); testExpr({$lastN: args}, [5, 7, 9]); args = { n: "$n", - output: "$a" + input: "$a" }; testExpr({$minN: args}, [1, 2, 3, 5]); testExpr({$maxN: args}, [9, 7, 5, 3]); @@ -64,7 +64,7 @@ testExpr({$firstN: args}, [1, 2, 3, 5]); testExpr({$lastN: args}, [3, 5, 7, 9]); args = { n: {$subtract: ["$n", "$diff"]}, - output: [3, 4, 5] + input: [3, 4, 5] }; testExpr({$minN: args}, [3, 4]); testExpr({$maxN: args}, [5, 4]); diff --git a/jstests/aggregation/sources/setWindowFields/n_accumulators.js b/jstests/aggregation/sources/setWindowFields/n_accumulators.js index 6a96d18d3f8..c0a1839df6a 100644 --- a/jstests/aggregation/sources/setWindowFields/n_accumulators.js +++ b/jstests/aggregation/sources/setWindowFields/n_accumulators.js @@ -22,7 +22,7 @@ if (!isExactTopNEnabled) { pipeline: [{ $setWindowFields: { sortBy: {ts: 1}, - output: {outputField: {[acc]: {n: 3, output: "$foo"}}}, + output: {outputField: {[acc]: {n: 3, input: "$foo"}}}, } }], cursor: {} @@ -39,7 +39,7 @@ seedWithTickerData(coll, nDocsPerTicker); for (const acc of nAccumulators) { for (const nValue of [4, 7, 12]) { jsTestLog("Testing accumulator " + tojson(acc) + " with 'n' set to " + tojson(nValue)); - testAccumAgainstGroup(coll, acc, [], {output: "$price", n: nValue}); + testAccumAgainstGroup(coll, acc, [], {input: "$price", n: nValue}); } // Verify that the accumulator will not throw if the 'n' expression evaluates to a constant. @@ -48,7 +48,7 @@ for (const acc of nAccumulators) { $setWindowFields: { partitionBy: "$ticker", sortBy: {_id: 1}, - output: {res: {[acc]: {n: {$add: [1, 2]}, output: "$price"}}} + output: {res: {[acc]: {n: {$add: [1, 2]}, input: "$price"}}} }, }, ]; @@ -74,19 +74,19 @@ for (const acc of nAccumulators) { testError({[acc]: "non object"}, expectedCode); testError({window: {documents: [-1, 1]}}, ErrorCodes.FailedToParse); testError({[acc]: {n: 2}, window: {documents: [-1, 1]}}, 5787907); - testError({[acc]: {output: "$foo"}, window: {documents: [-1, 1]}}, 5787906); - testError({[acc]: {output: "$foo", n: 2.1}, window: {documents: [-1, 1]}}, 5787903); + testError({[acc]: {input: "$foo"}, window: {documents: [-1, 1]}}, 5787906); + testError({[acc]: {input: "$foo", n: 2.1}, window: {documents: [-1, 1]}}, 5787903); // Invalid window specification. - testError({[acc]: {output: "$foo", n: 2.0}, window: [-1, 1]}, ErrorCodes.FailedToParse); + testError({[acc]: {input: "$foo", n: 2.0}, window: [-1, 1]}, ErrorCodes.FailedToParse); // Non constant argument for 'n'. - testError({[acc]: {output: "$foo", n: "$a"}, window: {documents: [-1, 1]}}, 5787902); + testError({[acc]: {input: "$foo", n: "$a"}, window: {documents: [-1, 1]}}, 5787902); // n = 0 - testError({[acc]: {output: "$foo", n: 0}, window: {documents: [-1, 1]}}, 5787908); + testError({[acc]: {input: "$foo", n: 0}, window: {documents: [-1, 1]}}, 5787908); // n < 0 - testError({[acc]: {output: "$foo", n: -100}, window: {documents: [-1, 1]}}, 5787908); + testError({[acc]: {input: "$foo", n: -100}, window: {documents: [-1, 1]}}, 5787908); } })(); \ No newline at end of file diff --git a/src/mongo/db/pipeline/accumulator_multi.cpp b/src/mongo/db/pipeline/accumulator_multi.cpp index 3430f527637..6cef4cd12c7 100644 --- a/src/mongo/db/pipeline/accumulator_multi.cpp +++ b/src/mongo/db/pipeline/accumulator_multi.cpp @@ -199,11 +199,11 @@ AccumulatorN::parseArgs(ExpressionContext* const expCtx, const BSONObj& args, VariablesParseState vps) { boost::intrusive_ptr n; - boost::intrusive_ptr output; + boost::intrusive_ptr input; for (auto&& element : args) { auto fieldName = element.fieldNameStringData(); - if (fieldName == kFieldNameOutput) { - output = Expression::parseOperand(expCtx, element, vps); + if (fieldName == kFieldNameInput) { + input = Expression::parseOperand(expCtx, element, vps); } else if (fieldName == kFieldNameN) { n = Expression::parseOperand(expCtx, element, vps); } else { @@ -211,8 +211,8 @@ AccumulatorN::parseArgs(ExpressionContext* const expCtx, } } uassert(5787906, str::stream() << "Missing value for '" << kFieldNameN << "'", n); - uassert(5787907, str::stream() << "Missing value for '" << kFieldNameOutput << "'", output); - return std::make_tuple(n, output); + uassert(5787907, str::stream() << "Missing value for '" << kFieldNameInput << "'", input); + return std::make_tuple(n, input); } void AccumulatorN::serializeHelper(const boost::intrusive_ptr& initializer, @@ -220,7 +220,7 @@ void AccumulatorN::serializeHelper(const boost::intrusive_ptr& initi bool explain, MutableDocument& md) { md.addField(kFieldNameN, Value(initializer->serialize(explain))); - md.addField(kFieldNameOutput, Value(argument->serialize(explain))); + md.addField(kFieldNameInput, Value(argument->serialize(explain))); } template @@ -241,7 +241,7 @@ AccumulationExpression AccumulatorMinMaxN::parseMinMaxN(ExpressionContext* const elem.type() == BSONType::Object); BSONObj obj = elem.embeddedObject(); - auto [n, output] = AccumulatorN::parseArgs(expCtx, obj, vps); + auto [n, input] = AccumulatorN::parseArgs(expCtx, obj, vps); auto factory = [expCtx] { if constexpr (s == MinMaxSense::kMin) { @@ -251,7 +251,7 @@ AccumulationExpression AccumulatorMinMaxN::parseMinMaxN(ExpressionContext* const } }; - return {std::move(n), std::move(output), std::move(factory), name}; + return {std::move(n), std::move(input), std::move(factory), name}; } void AccumulatorMinMaxN::processValue(const Value& val) { @@ -332,7 +332,7 @@ AccumulationExpression AccumulatorFirstLastN::parseFirstLastN(ExpressionContext* elem.type() == BSONType::Object); auto obj = elem.embeddedObject(); - auto [n, output] = AccumulatorN::parseArgs(expCtx, obj, vps); + auto [n, input] = AccumulatorN::parseArgs(expCtx, obj, vps); auto factory = [expCtx] { if constexpr (v == Sense::kFirst) { @@ -342,7 +342,7 @@ AccumulationExpression AccumulatorFirstLastN::parseFirstLastN(ExpressionContext* } }; - return {std::move(n), std::move(output), std::move(factory), name}; + return {std::move(n), std::move(input), std::move(factory), name}; } void AccumulatorFirstLastN::processValue(const Value& val) { diff --git a/src/mongo/db/pipeline/accumulator_multi.h b/src/mongo/db/pipeline/accumulator_multi.h index 17d534f2313..01fb33a53f2 100644 --- a/src/mongo/db/pipeline/accumulator_multi.h +++ b/src/mongo/db/pipeline/accumulator_multi.h @@ -42,14 +42,19 @@ namespace mongo { * has different criteria for how to pick values and order the final array, but any common behavior * shared by derived classes is implemented in this class. In particular: * - Initializing 'n' during 'startNewGroup'. - * - Parsing the expressions for 'n' and 'output'. + * - Parsing the expressions for 'n' and 'input'. */ class AccumulatorN : public AccumulatorState { public: static constexpr auto kFieldNameN = "n"_sd; - static constexpr auto kFieldNameOutput = "output"_sd; + static constexpr auto kFieldNameInput = "input"_sd; // Field names related to top/bottom/topN/bottomN. + + // Whereas other 'n' accumulators accept an 'input' parameter, top/bottom/topN/bottomN accept + // 'output'. This is done in order to disambiguate the expression that will be used to + // compute the output from the 'sortBy' expression, which will be used to order the output. + static constexpr auto kFieldNameOutput = "output"_sd; // Sort specification given by user. static constexpr auto kFieldNameSortBy = "sortBy"_sd; // Array containing only the fields needed to generate a sortKey from the input document. @@ -72,7 +77,7 @@ public: void startNewGroup(const Value& input) final; /** - * Helper which appends the 'n' and 'output' fields to 'md'. + * Helper which appends the 'n' and 'input' fields to 'md'. */ static void serializeHelper(const boost::intrusive_ptr& initializer, const boost::intrusive_ptr& argument, @@ -80,7 +85,7 @@ public: MutableDocument& md); protected: - // Parses 'args' for the 'n' and 'output' arguments that are common to the 'N' family of + // Parses 'args' for the 'n' and 'input' arguments that are common to the 'N' family of // accumulators. static std::tuple, boost::intrusive_ptr> parseArgs( ExpressionContext* expCtx, const BSONObj& args, VariablesParseState vps); diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp index 1b8c76c3eb1..3f6b6c73438 100644 --- a/src/mongo/db/pipeline/expression_test.cpp +++ b/src/mongo/db/pipeline/expression_test.cpp @@ -754,14 +754,14 @@ TEST(ExpressionFromAccumulators, FirstNLastN) { spec.firstElement(), Value(expected)); }; - firstNFn(fromjson("{$firstN: {n: 3, output: [19, 7, 28, 3, 5]}}"), + firstNFn(fromjson("{$firstN: {n: 3, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[19, 7, 28]"))); - firstNFn(fromjson("{$firstN: {n: 6, output: [19, 7, 28, 3, 5]}}"), + firstNFn(fromjson("{$firstN: {n: 6, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[19, 7, 28, 3, 5]"))); - firstNFn(fromjson("{$firstN: {n: 3, output: [1,2,3,4,5,6]}}"), BSONArray(fromjson("[1,2,3]"))); - firstNFn(fromjson("{$firstN: {n: 3, output: [1,2,null,null]}}"), + firstNFn(fromjson("{$firstN: {n: 3, input: [1,2,3,4,5,6]}}"), BSONArray(fromjson("[1,2,3]"))); + firstNFn(fromjson("{$firstN: {n: 3, input: [1,2,null,null]}}"), BSONArray(fromjson("[1,2,null]"))); - firstNFn(fromjson("{$firstN: {n: 3, output: [1.1, 2.713, 3, 3.4]}}"), + firstNFn(fromjson("{$firstN: {n: 3, input: [1.1, 2.713, 3, 3.4]}}"), BSONArray(fromjson("[1.1, 2.713, 3]"))); // $lastN @@ -770,13 +770,13 @@ TEST(ExpressionFromAccumulators, FirstNLastN) { spec.firstElement(), Value(expected)); }; - lastNFn(fromjson("{$lastN: {n: 3, output: [19, 7, 28, 3, 5]}}"), + lastNFn(fromjson("{$lastN: {n: 3, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[28,3,5]"))); - lastNFn(fromjson("{$lastN: {n: 6, output: [19, 7, 28, 3, 5]}}"), + lastNFn(fromjson("{$lastN: {n: 6, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[19, 7, 28, 3, 5]"))); - lastNFn(fromjson("{$lastN: {n: 3, output: [3,2,1,4,5,6]}}"), BSONArray(fromjson("[4,5,6]"))); - lastNFn(fromjson("{$lastN: {n: 3, output: [1,2,null,3]}}"), BSONArray(fromjson("[2,null,3]"))); - lastNFn(fromjson("{$lastN: {n: 3, output: [3, 2.713, 1.1, 2.7]}}"), + lastNFn(fromjson("{$lastN: {n: 3, input: [3,2,1,4,5,6]}}"), BSONArray(fromjson("[4,5,6]"))); + lastNFn(fromjson("{$lastN: {n: 3, input: [1,2,null,3]}}"), BSONArray(fromjson("[2,null,3]"))); + lastNFn(fromjson("{$lastN: {n: 3, input: [3, 2.713, 1.1, 2.7]}}"), BSONArray(fromjson("[2.713, 1.1, 2.7]"))); } @@ -811,13 +811,13 @@ TEST(ExpressionFromAccumulators, MinNMaxN) { }; // $maxN - maxNFn(fromjson("{$maxN: {n: 3, output: [19, 7, 28, 3, 5]}}"), + maxNFn(fromjson("{$maxN: {n: 3, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[28, 19, 7]"))); - maxNFn(fromjson("{$maxN: {n: 6, output: [19, 7, 28, 3, 5]}}"), + maxNFn(fromjson("{$maxN: {n: 6, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[28, 19, 7, 5, 3]"))); - maxNFn(fromjson("{$maxN: {n: 3, output: [1,2,3]}}"), BSONArray(fromjson("[3,2,1]"))); - maxNFn(fromjson("{$maxN: {n: 3, output: [1,2,null]}}"), BSONArray(fromjson("[2,1]"))); - maxNFn(fromjson("{$maxN: {n: 3, output: [1.1, 2.713, 3]}}"), + maxNFn(fromjson("{$maxN: {n: 3, input: [1,2,3]}}"), BSONArray(fromjson("[3,2,1]"))); + maxNFn(fromjson("{$maxN: {n: 3, input: [1,2,null]}}"), BSONArray(fromjson("[2,1]"))); + maxNFn(fromjson("{$maxN: {n: 3, input: [1.1, 2.713, 3]}}"), BSONArray(fromjson("[3, 2.713, 1.1]"))); auto minNFn = [&](const BSONObj& spec, const BSONArray& expected) { @@ -826,12 +826,12 @@ TEST(ExpressionFromAccumulators, MinNMaxN) { }; // $minN - minNFn(fromjson("{$minN: {n: 3, output: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[3,5,7]"))); - minNFn(fromjson("{$minN: {n: 6, output: [19, 7, 28, 3, 5]}}"), + minNFn(fromjson("{$minN: {n: 3, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[3,5,7]"))); + minNFn(fromjson("{$minN: {n: 6, input: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[3,5,7,19, 28]"))); - minNFn(fromjson("{$minN: {n: 3, output: [3,2,1]}}"), BSONArray(fromjson("[1,2,3]"))); - minNFn(fromjson("{$minN: {n: 3, output: [1,2,null]}}"), BSONArray(fromjson("[1,2]"))); - minNFn(fromjson("{$minN: {n: 3, output: [3, 2.713, 1.1]}}"), + minNFn(fromjson("{$minN: {n: 3, input: [3,2,1]}}"), BSONArray(fromjson("[1,2,3]"))); + minNFn(fromjson("{$minN: {n: 3, input: [1,2,null]}}"), BSONArray(fromjson("[1,2]"))); + minNFn(fromjson("{$minN: {n: 3, input: [3, 2.713, 1.1]}}"), BSONArray(fromjson("[1.1, 2.713, 3]"))); } -- cgit v1.2.1