summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@10gen.com>2021-11-05 02:49:23 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-11-05 03:15:33 +0000
commit32064f88ed311247af2b707a3560e57543aebcc8 (patch)
tree8b4a6dc795ad687306a1f0cfe63c888faada2823
parent6da66799d036cfb42e18a75ca9bd2272574a814d (diff)
downloadmongo-32064f88ed311247af2b707a3560e57543aebcc8.tar.gz
SERVER-59133 Change 'output' parameter to 'input' in syntax for $firstN/$lastN/$minN/$maxN
-rw-r--r--jstests/aggregation/accumulators/first_n_last_n.js17
-rw-r--r--jstests/aggregation/accumulators/min_n_max_n.js20
-rw-r--r--jstests/aggregation/expressions/n_expressions.js20
-rw-r--r--jstests/aggregation/sources/setWindowFields/n_accumulators.js18
-rw-r--r--src/mongo/db/pipeline/accumulator_multi.cpp20
-rw-r--r--src/mongo/db/pipeline/accumulator_multi.h13
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp40
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<Expression> n;
- boost::intrusive_ptr<Expression> output;
+ boost::intrusive_ptr<Expression> 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<Expression>& initializer,
@@ -220,7 +220,7 @@ void AccumulatorN::serializeHelper(const boost::intrusive_ptr<Expression>& 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 <MinMaxSense s>
@@ -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<Expression>& initializer,
const boost::intrusive_ptr<Expression>& 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<Expression>, boost::intrusive_ptr<Expression>> 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]")));
}