mongo/jstests/aggregation/expressions/map.js

79 lines
2.6 KiB
JavaScript

// SERVER-9841 $map expression to map over arrays
import {assertErrorCode} from "jstests/aggregation/extras/utils.js";
let t = db.server9841;
t.drop();
t.insert({
simple: [1, 2, 3, 4],
nested: [{a: 1}, {a: 2}],
mixed: [{a: 1}, {}, {a: 2}, {a: null}],
notArray: 1,
null: null,
});
function test(expression, expected) {
let result = t.aggregate({$project: {_id: 0, res: expression}}).toArray();
assert.eq(result, [{res: expected}]);
}
test({$map: {input: "$simple", as: "var", in: "$$var"}}, [1, 2, 3, 4]);
test({$map: {input: "$simple", as: "var", in: {$add: [10, "$$var"]}}}, [11, 12, 13, 14]);
test({$map: {input: "$simple", in: "$$this"}}, [1, 2, 3, 4]);
test({$map: {input: "$nested", as: "var", in: "$$var.a"}}, [1, 2]);
test({$map: {input: "$nested", as: "CURRENT", in: "$a"}}, [1, 2]);
test({$map: {input: "$mixed", as: "var", in: "$$var.a"}}, [1, null, 2, null]); // missing becomes null
test({$map: {input: "$null", as: "var", in: "$$var"}}, null);
// Nested behavior with two named variables.
test(
{
$map: {
input: "$simple",
as: "outer",
in: {$map: {input: "$simple", as: "inner", in: {$add: ["$$inner", "$$outer"]}}},
},
},
[
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8],
],
);
// Nested behavior for shadowing variables.
test({$map: {input: "$simple", in: {$map: {input: "$simple", in: "$$this"}}}}, [
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
]);
// Nested behavior with named inner variable and default outer variable.
test({$map: {input: "$simple", as: "outer", in: {$map: {input: "$simple", in: {$add: ["$$this", "$$outer"]}}}}}, [
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8],
]);
// can't use default if 'as' is defined
assertErrorCode(t, {$map: {input: "$simple", as: "value", in: "$$this"}}, 40324);
// can't set ROOT
assertErrorCode(t, {$project: {a: {$map: {input: "$simple", as: "ROOT", in: "$$ROOT"}}}}, ErrorCodes.FailedToParse);
// error on non-array
assertErrorCode(t, {$project: {a: {$map: {input: "$notArray", as: "var", in: "$$var"}}}}, 16883);
// parse errors (missing or extra fields)
assertErrorCode(t, {$project: {a: {$map: {x: 1, input: "$simple", as: "var", in: "$$var"}}}}, 16879);
assertErrorCode(t, {$project: {a: {$map: {as: "var", in: "$$var"}}}}, 16880);
assertErrorCode(t, {$project: {a: {$map: {input: "$simple", as: "var"}}}}, 16882);
// 'in' uses undefined variable name.
assertErrorCode(t, {$project: {a: {$map: {input: "$simple", in: "$$var"}}}}, 17276);