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).

see StackOverflow question.

EDIT:

  • Db version: 3.2.7

  • Translator version: MozJS-38

  • Javascript engine: mozjs

+3


source to share





All Articles