|
This also affects the $function and $accumulator aggregation operators, no doubt because they also go via MozJSImplScope::invoke(). However, in this case, the lack of a this object is less relevant for $function and $accumulator, because (unlike $where and map-reduce) they always set this to an empty object ($function, $accumulator init, accumulate/merge, finalize).
What ends up happening, when an arrow function is used, is that the function isn't run (confirmed by adding a print() inside the function, and checking for jsPrint in the logs), and the value used in lieu of the function's return value is the actual lambda function itself (ie. as BSON Code type):
> db.test_arrow_fn.drop()
|
false
|
> db.test_arrow_fn.insert({})
|
WriteResult({ "nInserted" : 1 })
|
> db.test_arrow_fn.aggregate( [ { $project: { _id: {
|
$function: {
|
body: function(a,b,c) { return [ a, b, c ]; },
|
args: [1,2,3],
|
lang: "js" } } } } ] ).toArray()
|
[ { "_id" : [ 1, 2, 3 ] } ]
|
> db.test_arrow_fn.aggregate( [ { $project: { _id: {
|
$function: {
|
body: (a,b,c) => [ a, b, c ],
|
args: [1,2,3],
|
lang: "js" } } } } ] ).toArray()
|
[ { "_id" : { "code" : "(a,b,c) => [ a, b, c ]" } } ]
|
// But the expected output is the same as above, ie: [ { "_id" : [ 1, 2, 3 ] } ]
|
>
|
>
|
> db.test_arrow_fn.aggregate( [ { $group: { _id: 1, foo: {
|
$accumulator: {
|
init: function(a,b,c) { return [ "init", a, b, c ]; },
|
initArgs: [1,2,3],
|
accumulate: function(a,b,c) { return [ "acc", a, b, c ]; },
|
accumulateArgs: [1,2,3],
|
merge: function(a, b, c) { return [ "merge", a, b, c ]; },
|
finalize: function(a, b, c) { return [ "finalize", a, b, c ]; },
|
lang: "js" } } } } ] ).toArray()
|
[
|
{
|
"_id" : 1,
|
"foo" : [
|
"finalize",
|
[
|
"acc",
|
[
|
"init",
|
1,
|
2,
|
3
|
],
|
1,
|
2
|
],
|
undefined,
|
undefined
|
]
|
}
|
]
|
> db.test_arrow_fn.aggregate( [ { $group: { _id: 1, foo: {
|
$accumulator: {
|
init: (a,b,c) => [ "init", a, b, c ],
|
initArgs: [1,2,3],
|
accumulate: (a,b,c) => [ "acc", a, b, c ],
|
accumulateArgs: [1,2,3],
|
merge: (a, b, c) => [ "merge", a, b, c ],
|
finalize: (a, b, c) => [ "finalize", a, b, c ],
|
lang: "js" } } } } ] ).toArray()
|
[
|
{
|
"_id" : 1,
|
"foo" : {
|
"code" : "(a, b, c) => [ \"finalize\", a, b, c ]"
|
}
|
}
|
]
|
> db.test_arrow_fn.aggregate( [ { $group: { _id: 1, foo: {
|
$accumulator: {
|
init: (a,b,c) => [ "init", a, b, c ],
|
initArgs: [1,2,3],
|
accumulate: (a,b,c) => [ "acc", a, b, c ],
|
accumulateArgs: [1,2,3],
|
merge: (a, b, c) => [ "merge", a, b, c ],
|
finalize: function (a, b, c) { return [ "finalize", a, b, c ]; },
|
lang: "js" } } } } ] ).toArray()
|
[
|
{
|
"_id" : 1,
|
"foo" : [
|
"finalize",
|
{
|
"code" : "function() { return (a,b,c) => [ \"acc\", a, b, c ] }"
|
},
|
undefined,
|
undefined
|
]
|
}
|
]
|
>
|
|