MongoDB MapReduce就地更新如何

MongoDB MapReduce就地更新如何,mapreduce,mongodb,Mapreduce,Mongodb,*基本上,我试着根据过去一个小时的分数来排序对象 我正在尝试为数据库中的对象生成每小时的投票总数。投票将嵌入到每个对象中。对象架构如下所示: { _id: ObjectId score: int hourly-score: int <- need to update this value so I can order by it recently-voted: boolean votes: { "4e4634821dff6f103c0

*基本上,我试着根据过去一个小时的分数来排序对象

我正在尝试为数据库中的对象生成每小时的投票总数。投票将嵌入到每个对象中。对象架构如下所示:

{
    _id: ObjectId
    score: int
    hourly-score: int <- need to update this value so I can order by it
    recently-voted: boolean
    votes: {
        "4e4634821dff6f103c040000": { <- Key is __toString of voter ObjectId
            "_id": ObjectId("4e4634821dff6f103c040000"), <- Voter ObjectId
            "a": 1, <- Vote amount
            "ca": ISODate("2011-08-16T00:01:34.975Z"), <- Created at MongoDate
            "ts": 1313452894 <- Created at timestamp
        },
        ... repeat ...
    }
}
这个问题实际上与我几天前问的一个问题有关

我该怎么做?运行MapReduce命令以执行以下操作:

仅在最近投票=真或小时分数>0的对象上运行。 计算最后一小时内创建的投票总数。 更新时薪=上述计算的总和,最近投票=假。 我还了解到,通过在M/R命令之前运行DB.getMongo.setSlaveOk,可以在从属数据库上执行MapReduce。我可以在从机上运行reduce并更新主数据库吗


使用Mongo MapReduce是否可以进行就地更新?

您完全可以做到这一点。我将逐一回答您的问题:

一,。 您可以在map reduce中指定一个查询,该查询过滤将传递到map阶段的对象集。在mongo shell中,这看起来像是假设m和r分别是映射器和减速器函数的名称:

> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
二,。 步骤1将允许您在过去一小时内至少有一票或最近投票设置为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;
}
三,。 要更新小时分数表,可以使用reduceOutput选项映射reduce,该选项将使用发出的值和输出集合中以前保存的值(如果有)调用reducer。该过程的结果将保存到输出集合中。这看起来像:

> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
除了重新减少输出外,您还可以使用merge,它将用新创建的文档覆盖输出集合中的文档,但会留下任何_id不同于m-r作业创建的_id的文档,replace,这实际上是一种拖放和创建操作,是默认操作,或者使用{inline:1},将结果直接返回到shell或驱动程序。请注意,在使用{inline:1}时,您的结果必须适合最近MongoDB版本中单个文档16MB的大小

四,。
您可以在辅助设备从属设备上运行map reduce作业,但由于辅助设备无法接受写操作,这正是它们成为辅助设备的原因,因此您只能在使用内联输出时执行此操作。

Ok在第3步之前,所有操作都是有意义的。我不太明白如何获取减少的每小时分数总和并更新集合中的相关对象。假设我们有一个集合评论,其中包含我问题中的模式,我想将所有相关评论每小时分数更新为新的减少的总和。小时分数是注释对象的参数,而不是单独集合中的某个参数。我该怎么做呢?哦,我明白了-你想把“小时分数”字段更新为“投票金额”字段投票的总和。a随着地图的输出减少?我不认为你可以用map reduce来做这件事,但是你绝对可以做一个后处理步骤,使用map reduce输出来更新你想要的任何集合。嗯,好的。从关系数据库来看,这是一项相当简单的任务。基本上我想做的就是在过去的一个小时里按分数排列物品。在关系数据库中,我会将分数保存在单独的表中。然后我从objects表中选择join scores表,对过去一个小时的分数进行求和,并按该总和排序。也许是a。mongo根本不适合这个或b。我没有正确组织我的对象/投票?我建议使用cron'd脚本运行map reduce,然后立即使用其输出更新初始表。是的,我倾向于这样做,至少目前是这样。非常感谢你的回答。