Основная проблема заключается в том, что переменная this
переназначается для каждого вызова функции.
Для демонстрации я выполнил короткий тест из оболочки mon go.
Создаю коллекцию, содержащую 1 документ:
MongoDB Enterprise replset:PRIMARY> db.maptest.find({},{_id:0})
{ "canary" : "tweet" }
Затем создайте сохраненную функцию который будет принимать аргумент, выдавать 2 значения, одно с использованием this
, а другое с использованием переданного аргумента:
MongoDB Enterprise replset:PRIMARY> db.system.js.find()
{ "_id" : "testfun", "value" : { "code" : "function(arg){emit(\"this.canary\",this.canary),emit(\"arg.canary\",arg.canary)}" } }
Затем использовать хранимую функцию в вызове mapReduce:
MongoDB Enterprise replset:PRIMARY> db.maptest.mapReduce(function(){testfun(this)},function(a,b){return {a:a,b:b}},{out:{inline:1}})
{
"results" : [
{
"_id" : "arg.canary",
"value" : "tweet"
},
{
"_id" : "this.canary",
"value" : undefined
}
],
...
As Вы можете видеть, что this.canary
был неопределен, но arg.canary
содержал значение из входного документа.
Каркас mapReduce назначает this
документу, который в данный момент проверяется при вызове функции карты. Когда хранимая функция вызывается из функции карты, она получает свою собственную this
. Однако, вызывая функцию как testfun(this)
, исходный this
контекст функции карты предоставляется хранимой функции в качестве аргумента.