[javascript] передать переменную в функцию по значению
задай её хардкодом, там сигнатура жестко задана и структура (которая emit) не должна меняться
задай её хардкодом, там сигнатура жестко задана и структура (которая emit) не должна менятьсяНе понял. Как я её могу хардкодить, если мне её надо передавать параметром в вышестоящую функцию?
надо смотреть в сторону apply
http://www.alistapart.com/articles/getoutbindingsituations/
http://www.alistapart.com/articles/getoutbindingsituations/
Прикольно, только непонятно, что делать с учётом того, что в качестве this у mapFunction уже выступает объект.
Попробовал заэпплаить объект на finalize-функцию, которой не нужен this, по аналогии с примером по ссылке, как ни извращаюсь, в итоге всё равно где-то передаётся объект или функция, ссылающиеся на исходную переменную, и либо этот объект, либо сама переменная не определены.
Типа такого:
Пробовал вынести theObj уровнем выше — тоже не помогло.
Типа такого:
function createFinalizeFunction {
return function {
var theObj = {
'x': x
};
return (function(k, v) {
v.x *= this.x;
return v;
}).apply(theObj, arguments);
};
}
return db[someParam].mapReduce(
mapFunction,
reduceFunction,
{
query:{k:kk},
out:{inline:1},
finalize:createFinalizeFunction
}).results;
};
Пробовал вынести theObj уровнем выше — тоже не помогло.
Как минимум в PHP при вызове функции map/reduce ей можно передать параметры в виде
Переменные xxx и yyy появятся в глобальной области видимости внутри map/reduce функций. Они по понятным причинам будут readOnly, но это тебе не помешает, я так понял.
$params = array(
'mapreduce' => $collectionName,
'map' => $map,
'reduce' => $reduce,
'query' => $query,
'scope' => array('xxx' => 5, 'yyy' => 6)
);
Переменные xxx и yyy появятся в глобальной области видимости внутри map/reduce функций. Они по понятным причинам будут readOnly, но это тебе не помешает, я так понял.
Вообще на скользкую дорожку ты встал
Мы с этой монгой уже почти год ебемся... Очень уж много у нее неприятных особенностей.
Мы с этой монгой уже почти год ебемся... Очень уж много у нее неприятных особенностей.Из документации по монге:
scope - то, что тебе нужно.
db.runCommand(
{ mapreduce : <collection>,
map : <mapfunction>,
reduce : <reducefunction>
[, query : <query filter object>]
[, sort : <sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces>]
[, limit : <number of objects to return from collection>]
[, out : <see output options below>]
[, keeptemp: <true|false>]
[, finalize : <finalizefunction>]
[, scope : <object where fields go into javascript global scope >]
[, jsMode : true]
[, verbose : true]
}
);
scope - то, что тебе нужно.
Переменные xxx и yyy появятся в глобальной области видимости внутри map/reduce функций. Они по понятным причинам будут readOnly, но это тебе не помешает, я так понял.Это конечно интереснее, но есть несколько моментов:
1. Тогда уж переменные можно "захардкодить", подставив в $map
2. Мне кажется, что если передавать код каждый раз по сети, это будет сильно медленнее, чем если вызывать серверную процедуру (которая в db.system.js хранится передавая ей только параметры Я неправ?
3. На самом деле возвращается не mapReduce а
return db[coll].mapReduce(...).results.sort(sortFunction).slice(10);Такой вызов, как я понимаю, уже из пхп не провернёшь.
Во втором моем сообщении - выдержка из мануала по монге. В качестве map или reduce можно передать как сам текст функции, так и название заранее сохраненной функции.
И кстати насчет медленнее. Map/reduce в монге и так настолько медленный, что разница в передаче функции по сети будет о-малое от времени выполнения. А учитывая, что один инстанс mongod может в каждый момент времени выполнять только один map/reduce, использовать этот механизм для реалтайм-запросов становится очень сложно.
И кстати насчет медленнее. Map/reduce в монге и так настолько медленный, что разница в передаче функции по сети будет о-малое от времени выполнения. А учитывая, что один инстанс mongod может в каждый момент времени выполнять только один map/reduce, использовать этот механизм для реалтайм-запросов становится очень сложно.Фак! Я, когда читал мануал, думал, что, когда они говорят про однопоточность mapReduce, они имеют в виду, что сам js не параллелится. Пидарасы! Тогда один хер проще через find делать и на сервере отсекать лишнее.
Чувак, с которым я общался на монго-конфе в Москве (Mathias Stearn, разработчик MongoDB Core Server сказал, что как минимум до 2.2 к лучшему ничего не изменится. К 2.2 они обещали прикрутить гугловский V8 вместо SpiderMonkey, он должен уметь многопоточность.
Интересно, что им мешает создавать несколько инстансов SpiderMonkey.
а как блокировки разрешаться будут? Думаю, они оставили это движку (если инстанс всего один).
гугловский V8 вместо SpiderMonkey, он должен уметь многопоточностьпоходу они его не сумели приготовить
у нас несколько лет в продакшене работает SpiderMonkey, с десятками и сотнями потоков
Оставить комментарий
doublemother
В чём суть проблемы: хочу я сделать в монге некую функцию для map-reduce:var myfun = function(someParam, x, kk, ...) {function mapFunction {
var obj = this;
obj.x *= x;
emit(this._id, obj);
}
function reduceFunction(id, val) {
return val[0];
}
return db[someParam].mapReduce(mapFunction, reduceFunction, {query:{k:kk}, out:{inline:1}}).results;
}
В результате у меня при вызове случается ошибка:
Wed Oct 26 17:02:12 uncaught exception: map reduce failed:{"assertion" : "map invoke failed: JS Error: ReferenceError: x is not defined nofile_b:2",
"assertionCode" : 9014,
"errmsg" : "db assertion failure",
"ok" : 0
}
Насколько я понимаю, это всё из-за того, что при попадании в недра mapReduce mapFunction уже не знает ни о каком x. Можно ли как-то создать функцию mapFunction, чтобы x в ней было просто константой и не терялось?