返回首页 Mongodb 教程

教程

高级教程

Map Reduce

在 MongoDB 文档中,Map-Reduce(映射归约)是一种将大量数据压缩成有用的聚合结果的数据处理范式。MongoDB 使用 mapReduce 命令来实现映射归约操作。映射归约通常用来处理大型数据。

映射归约命令

mapReduce 命令的基本格式为:

>db.collection.mapReduce(
   function() {emit(key,value);},  //map function
   function(key,values) {return reduceFunction},   //reduce function
   {
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)

mapReduce 函数首先查询集合,然后将结果文档利用 emit 函数映射为键值对,然后再根据有多个值的键来简化。

上述语法格式中:

  • map 一个 JavaScript 函数,将一个值与键对应起来,并生成键值对。
  • reduce 一个 JavaScript 函数,用来减少或组合所有拥有同一键的文档。
  • out 指定映射归约查询结果的位置。
  • query 指定选择文档所用的选择标准(可选的)。
  • sort 指定可选的排序标准。
  • limit 指定返回的文档的最大数量值(可选的)。

使用 mapReduce

以下面这个存储用户发帖的文档结构。该文档存储用户的用户名(user_name)和发帖状态(status)。

{
   "post_text": "tutorialspoint is an awesome website for tutorials",
   "user_name": "mark",
   "status":"active"
}

posts 集合上使用 mapReduce 函数选择所有的活跃帖子,将它们基于用户名组合起来,然后计算每个用户的发帖量。代码如下:

>db.posts.mapReduce( 
   function() { emit(this.user_id,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
)

上面的 mapReduce 查询输出结果如下:

{
   "result" : "post_total",
   "timeMillis" : 9,
   "counts" : {
      "input" : 4,
      "emit" : 4,
      "reduce" : 2,
      "output" : 2
   },
   "ok" : 1,
}

结果显示,只有 4 个文档符合查询条件(status:"active"),于是 map 函数就生成了 4 个带有键值对的文档,而最终 reduce 函数将具有相同键值的映射文档变为了 2 个。

要想查看 mapReduce 查询的结果,使用 find 操作符。

>db.posts.mapReduce( 
   function() { emit(this.user_id,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
).find()

上述查询的结果如下,显示出用户 tom 和 mark 都发了 2 个活跃的帖子。

{ "_id" : "tom", "value" : 2 }
{ "_id" : "mark", "value" : 2 }

MapReduce 查询同样也可以用来构建大型复杂的聚合查询,自定义 JavaScript 函数使得 MapReduce 更为灵活与强大。

上一篇: ObjectId 下一篇: 全文检索