课程表

MongoDB 基础教程

MongoDB 高级教程

工具箱
速查手册

MongoDB Map Reduce

当前位置:免费教程 » 数据库/运维 » MongoDB

Map-Reduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。

MongoDB提供的Map-Reduce非常灵活,对于大规模数据分析也相当实用。


MapReduce 命令

以下是MapReduce的基本语法:

  1. >db.collection.mapReduce(
  2. function() {emit(key,value);}, //map 函数
  3. function(key,values) {return reduceFunction}, //reduce 函数
  4. {
  5. out: collection,
  6. query: document,
  7. sort: document,
  8. limit: number
  9. }
  10. )

使用 MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调用 emit(key, value), 遍历 collection 中所有的记录, 将key 与 value 传递给 Reduce 函数进行处理。

Map 函数必须调用 emit(key, value) 返回键值对。

参数说明:

  • map :映射函数 (生成键值对序列,作为 reduce 函数参数)。
  • reduce 统计函数,reduce函数的任务就是将key-values变成key-value,也就是把values数组变成一个单一的值value。。
  • out 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
  • query 一个筛选条件,只有满足条件的文档才会调用map函数。(query。limit,sort可以随意组合)
  • sort 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
  • limit 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)

使用 MapReduce

考虑以下文档结构存储用户的文章,文档存储了用户的 user_name 和文章的 status 字段:

  1. >db.posts.insert({
  2. "post_text": "W3xue教程,最全的技术文档。",
  3. "user_name": "mark",
  4. "status":"active"
  5. })
  6. WriteResult({ "nInserted" : 1 })
  7. >db.posts.insert({
  8. "post_text": "W3xue教程,最全的技术文档。",
  9. "user_name": "mark",
  10. "status":"active"
  11. })
  12. WriteResult({ "nInserted" : 1 })
  13. >db.posts.insert({
  14. "post_text": "W3xue教程,最全的技术文档。",
  15. "user_name": "mark",
  16. "status":"active"
  17. })
  18. WriteResult({ "nInserted" : 1 })
  19. >db.posts.insert({
  20. "post_text": "W3xue教程,最全的技术文档。",
  21. "user_name": "mark",
  22. "status":"active"
  23. })
  24. WriteResult({ "nInserted" : 1 })
  25. >db.posts.insert({
  26. "post_text": "W3xue教程,最全的技术文档。",
  27. "user_name": "mark",
  28. "status":"disabled"
  29. })
  30. WriteResult({ "nInserted" : 1 })
  31. >db.posts.insert({
  32. "post_text": "W3xue教程,最全的技术文档。",
  33. "user_name": "W3xue",
  34. "status":"disabled"
  35. })
  36. WriteResult({ "nInserted" : 1 })
  37. >db.posts.insert({
  38. "post_text": "W3xue教程,最全的技术文档。",
  39. "user_name": "W3xue",
  40. "status":"disabled"
  41. })
  42. WriteResult({ "nInserted" : 1 })
  43. >db.posts.insert({
  44. "post_text": "W3xue教程,最全的技术文档。",
  45. "user_name": "W3xue",
  46. "status":"active"
  47. })
  48. WriteResult({ "nInserted" : 1 })

现在,我们将在 posts 集合中使用 mapReduce 函数来选取已发布的文章(status:"active"),并通过user_name分组,计算每个用户的文章数:

  1. >db.posts.mapReduce(
  2. function() { emit(this.user_name,1); },
  3. function(key, values) {return Array.sum(values)},
  4. {
  5. query:{status:"active"},
  6. out:"post_total"
  7. }
  8. )

以上 mapReduce 输出结果为:

  1. {
  2. "result" : "post_total",
  3. "timeMillis" : 23,
  4. "counts" : {
  5. "input" : 5,
  6. "emit" : 5,
  7. "reduce" : 1,
  8. "output" : 2
  9. },
  10. "ok" : 1
  11. }

结果表明,共有4个符合查询条件(status:"active")的文档, 在map函数中生成了4个键值对文档,最后使用reduce函数将相同的键值分为两组。

具体参数说明:

  • result:储存结果的collection的名字,这是个临时集合,MapReduce的连接关闭后自动就被删除了。
  • timeMillis:执行花费的时间,毫秒为单位
  • input:满足条件被发送到map函数的文档个数
  • emit:在map函数中emit被调用的次数,也就是所有集合中的数据总量
  • ouput:结果集合中的文档个数(count对调试非常有帮助)
  • ok:是否成功,成功为1
  • err:如果失败,这里可以有失败原因,不过从经验上来看,原因比较模糊,作用不大

使用 find 操作符来查看 mapReduce 的查询结果:

  1. >db.posts.mapReduce(
  2. function() { emit(this.user_name,1); },
  3. function(key, values) {return Array.sum(values)},
  4. {
  5. query:{status:"active"},
  6. out:"post_total"
  7. }
  8. ).find()

以上查询显示如下结果,两个用户 tom 和 mark 有两个发布的文章:

  1. { "_id" : "mark", "value" : 4 }
  2. { "_id" : "W3xue", "value" : 1 }

用类似的方式,MapReduce可以被用来构建大型复杂的聚合查询。

Map函数和Reduce函数可以使用 JavaScript 来实现,使得MapReduce的使用非常灵活和强大。

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号