开发者社区> 问答> 正文

Mongodb的mapreduce如何实现只更新现有表的部分字段

MapRedue 的输出

{"out", option }
option可以是下面几个选项:
•"collection name" – mapReduce的输出结果会替换掉原来的collection,collection不存在则创建
•{ replace : "collection name" } – 同上
•{ merge : "collection name" } – 将新老数据进行合并,新的替换旧的,没有的添加进去
•{ reduce : "collection name" } – 存在老数据时,在原来基础上加新数据(即 new value = old value + mapReduce value)

{ inline : 1 } – 不会创建collection,结果保存在内存里,只限于结果小于16MB的情况
如果用collection name作option不能与其它option一起使用,其它则可以,如:
◦{ "out", { replace : "collection name", db : "db name" } }
merge选项的可能性最大,但是经过实验发现,它总是会根据“_id”更新整个文档,而不是只更新reduce或者finalize出来的对象里有的字段。
比如我一个已经存在的集合A,有10几个字段,没有emps字段,我运行一个MR操作,reduce出来的是{key,emps:[["0132",70],["1443",30]]},想把emps字段添加到现有的集合A上,结果我10几个字段都没有了,就只剩下emps字段了。
本来想在reduce里引用db对象手工update的,但是现在的版本都不让引用db对象了。
现在只能在mapreduce后,执行一个forEach,手工执行update。
请问mapreduce有没有相应的解决方案。

展开
收起
蛮大人123 2016-02-19 11:22:50 2698 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    用 reduce,他会把你在结果集中 已经存在的结果 和 新计算出来的结果 用你提供的 reduce function (reducer) 算一遍,把最后结果存下来。这里最重要的让 mapper 输出的中间结果跟最终结果有相同的格式。这样一个reducer用在两个地方,一次在 reduce 中,一次在输出中,如果他们有相同的格式,尤其是层次,就容易写好多。可以把 reducer 理解成只负责合并多个结果,如果 mapper 只输出一个中间结果,它就应该可以不经过reducer,直接作为最终结果。实际上,MongoDB中,当一个key只对应一个mapper输出的时候,的确是不经过reducer的直接输出的。
    https://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/#output-to-a-collection-with-an-action

    Merge the new result with the existing result if the output collection already exists. If an existing document has the same key as the new result, apply the reduce function to both the new and the existing documents and overwrite the existing document with the result.

    2019-07-17 18:44:29
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
MongoDB多数据中心的方案选型之路 立即下载
阿里云MongoDB云服务构建 立即下载
饿了么高级架构师陈东明:MongoDB是如何逐步提高可靠性的 立即下载