我刚刚开始在 mongo 中使用 MapReduce,并使用复合键(日期,候选人)进行查询,该查询返回与该键关联的值(当天该候选人的总票数)。我真正想要的是每个日期的票数都是累积的。也就是说,对于每个日期/候选人键,该值是在该日期和之前为该候选人投出的所有选票的总和。
这是我当前的代码:
示例输入:
{
"interaction" : {
"type" : "draft",
"parameters" : {
"value" : [
{
"candidate" : 453510,
"votes" : 2
},
{
"candidate" : 325786,
"votes" : 2
}
]
}
},
"created_at" : 1360796255
}
地图:
var mapFn = function() {
var right = function(str, n) {
return str.substring(str.length, str.length - n);
}
var toDate = function(epochTimeSec) {
var d = new Date(1000 * epochTimeSec);
var yr = d.getYear() + 1900;
var mn = d.getMonth() + 1;
var dt = d.getDate();
return '' + right('0000' + yr, 4) + '-' + right('00' + mn, 2) + '-' + right('00' + dt, 2);
}
for(var i=0; i<this.interaction.parameters.value.length; i++)
{
vote = this.interaction.parameters.value[i];
var creationDate = toDate(this.created_at);
var votedCandidate = vote.candidate;
emit( {date: creationDate, candidate: votedCandidate}, { quantity: candidate.quantity } );
}
}
减少:
var reduceFn = function(key, values) {
var sum = 0;
values.forEach(function(doc) {
sum += doc.quantity;
});
return { quantity: sum };
}
输出:
db.collection_mr.drop();
db.collection.mapReduce(mapFn, reduceFn, { out: 'collection_mr' } );
function printData(r) {
print(r._id.date + ", " + r._id.candidate + ", " + r.value.quantity);
}
db.collection_mr.find().forEach(printData);
感谢您的任何帮助!
编辑
作为对评论的回应,我提供了一个示例输入。澄清一下——上面的代码正确地返回了每个日期所有投票的总和。但是,我想对其进行修改,以返回每个日期在该日期或之前投票的所有投票总数。
回答 Asya Kamsky,这是临时手动运行的,因此需要在输入日期(可能不是当前日期)之前输出所有数据。