Using arrow functions in MapReduce MongoDB functions
I am playing with arrows MongoDB
to write MapReduce jobs and I have noticed some strange behavior.
I have a collection of students as follows:
{ "_id" : ObjectId("58ff3520704bd5539fe9dc7b"), "stud_id" : "x0000003", "name" : "david smith", "class" : "InfMgt", "weekNo" : 2, "attendencesThisWeek" : 4 }
{ "_id" : ObjectId("58ff3520704bd5539fe9dc7c"), "stud_id" : "x0000003", "name" : "david smith", "class" : "InfMgt", "weekNo" : 3, "attendencesThisWeek" : 2 }
{ "_id" : ObjectId("58ff3543704bd5539fe9dc7d"), "stud_id" : "x0000001", "name" : "sean smith", "class" : "edt", "weekNo" : 1, "attendencesThisWeek" : 2 }
{ "_id" : ObjectId("58ff3543704bd5539fe9dc7e"), "stud_id" : "x0000001", "name" : "sean smith", "class" : "edt", "weekNo" : 2, "attendencesThisWeek" : 2 }
...
Now my task is to write a MapReduce task that will determine the total number of visits for each student up to that date, so I started writing my functions with arrows:
Function Map
const mapFunc = () => emit(this.stud_id, this.attendencesThisWeek)
It is not calling anything, after searching the web, I found that the arrow function already has this
which makes it unusable as a map function here
inside the arrow function, this and the arguments refer to the values this and the arguments in the environment, the arrow function is defined in (ie "outside" the arrow function)
So, I rewrote my function in the "classic" way:
const mapFunc2 = function() {emit(this.stud_id, this.attendencesThisWeek)}
(I still use const
to make sure nothing changes the function or reassigns to mapFunc2
)
Reduce function
When this was done, I did, however, that the problem with the shortening function shouldn't be a problem since it doesn't use the keyword this
.
I made a mistake!
const reduceFunc = (key, countAttendencesThisWeek) => Array.sum(countAttendencesThisWeek)
Gets some pretty funny results:
{ "_id" : "x0000002", "value" : (key, countAttendencesThisWeek) => Array.sum(countAttendencesThisWeek) }
{ "_id" : "x0000003", "value" : (key, countAttendencesThisWeek) => Array.sum(countAttendencesThisWeek) }
Moving on to the same answer overflow, I read the following:
ES2015 distinguishes between functions that are called and functions that are constructive. If the function is constructive, it can be with a new, that is, new user (). If a function is callable, it can be (i.e. a call to a normal function).
Functions created via function declarations / expressions are both constructive and callable. Arrow functions (and methods) are only revoked. Class constructors are only constructive.
I am assuming MongoDB is calling the shorten function in a way that makes it unapproachable as an arrow function, but this is where I need help to understand what is actually going on.
I changed the shortening function back to the "classic" version:
const reduceFunc2 = function(keyStudId, attendences) { return Array.sum(attendences) }
That's fine, but I'm not interested in why the arrow function is unusable here.
Thanks for reading, it might not be important for real programmers who have learned this, but I think that after a few years some colleges start teaching functional functions, and arrow functions, for example, are becoming the norm, it will be rather strange for those developers who must adapt (if you don't understand why everything works this way).
EDIT:
- Db version:
3.2.7
- Translator version:
MozJS-38
- Javascript engine:
mozjs
source to share
No one has answered this question yet
See similar questions:
or similar: