Вы определенно можете сделать это. Я отвечу на ваши вопросы по одному:
1.
Вы можете указать запрос вместе со своей картой-редукции, которая фильтрует набор объектов, которые будут переданы в фазу карты. В оболочке mongo это будет выглядеть так (при условии, что m
и r
являются именами функций вашего картографа и редуктора соответственно):
> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
2.
Шаг # 1 позволит вам использовать свой картограф для всех документов с хотя бы одним голосом за последний час (или если для recently-voted
установлено значение true), но не все голоса были за последний час. Таким образом, вам нужно отфильтровать список в вашем картографическом списке и выдавать только те голоса, которые вы хотите подсчитать:
function m() {
var hour_ago = new Date() - 3600000;
this.votes.forEach(function (vote) {
if (vote.ts > hour_ago) {
emit(/* your key */, this.vote.a);
}
});
}
И уменьшить:
function r(key, values) {
var sum = 0;
values.forEach(function(value) { sum += value; });
return sum;
}
3.
Чтобы обновить таблицу почасовых оценок, вы можете использовать опцию reduceOutput
для отображения-уменьшения, которая вызовет ваш редуктор как с выданными значениями, так и с ранее сохраненным значением в выходной коллекции (если есть). Результат этого прохода будет сохранен в выходной коллекции. Это выглядит так:
> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
В дополнение к повторному сокращению вывода вы можете использовать merge
, который будет перезаписывать документы в выходной коллекции на вновь созданные (но оставляя после себя любые документы с _id
, отличным от _id
, созданных вашим mr job), replace
, которая по сути является операцией удаления и создания и используется по умолчанию, или используйте {inline: 1}
, которая будет возвращать результаты непосредственно в оболочку или в ваш драйвер. Обратите внимание, что при использовании {inline: 1}
ваши результаты должны соответствовать размеру, разрешенному для одного документа (16 МБ в последних выпусках MongoDB).
(4).
Вы можете запускать задания уменьшения карты на вторичных серверах («ведомых»), но поскольку вторичные серверы не могут принимать записи (именно это делает их вторичными), это можно сделать только при использовании встроенного вывода.