MongoDB学习日记(十):聚合

这篇博客详细介绍了MongoDB的聚合操作,包括aggregate()、count()、distinct()、group()、mapReduce和runCommand()。通过实例解析了每个方法的功能和用法,如aggregate()用于复杂查询,count()计算结果数量,distinct()去除重复项,group()和mapReduce()进行数据分组和简化。同时,提到了runCommand()执行特定命令的功能,以及mapReduce()中map和reduce函数的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里,我整理了一些学到的复杂方法,并不全面,希望有用。


aggregate()

假如有以下数据:(引用 MongoDB 官网例子)

{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }

执行以下操作:

db.orders.aggregate([
                     { $match: { status: "A" } },
                     { $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
                     { $sort: { total: -1 } }
                   ])

结果如下:

{ "_id" : "xyz1", "total" : 100 }
{ "_id" : "abc1", "total" : 75 }

解析: $match 是用来匹配查询条件,不可以在 find( ) 中使用;$sort 之前也讲过,这里为 -1 表示倒序排序;重点是 $group ,可以看到 _id: "$cust_id" 这段代码的意思 cust_id 字段重命名为 _id$sum 方法可以计算 amount 的总和。这里需要注意 cust_idamount 前都加了 $ 符号。


count()

db.user.count( { name : "MongoDB" } )

这里写图片描述

count() 的作用可见,就是计算查询出的结果的总数。


distinct()

distinct() 的作用是去除重复,但是得到的不是查询的全部结果,而是对应字段。

db.user.distinct( "name" )

这里写图片描述


group()

group()$group 的作用其实是一致的,不过一个是方法一个是语法。

group( ) 有如下参数:

  • key 分组依据
  • initial 指定表
  • $reduce : function( cur, prev ) { } 分组执行函数(第一个参数是当前文档对象,第二个参数是上一次function操作的累计对象)
db.user.group({
    "key" : { "age" : true },
    "initial" : { "user" : [] },
    "$reduce" : function( cur, prev ) {
      prev.user.push( cur.name );
    }
})

/*或*/

db.user.group({
    key : { "age" : true },
    initial : { "user" : [] },
    $reduce : function( cur, prev ) {
      prev.user.push( cur.name );
    }
})

这里写图片描述

group( ) 还提供了其他参数 :

  • condition 过滤条件。
  • finalize : function( out ) {} 这是个函数,每一组文档执行完后,都会触发此方法,那么在每组集合里面加上count也就是它的总和了。
db.user.group({
    key : { "age" : true },
    initial : { "user" : [] },
    $reduce : function( cur, prev ) {
      prev.user.push( cur.name );
    },
    finalize : function( out ) {
      out.count = out.user.length;
    },
    condition : { "age" : { $gt : 10 } }
})

这里写图片描述


mapReduce( )

语法:

mapReduce( /*map*/function , /*reduce*/fucntion , { out : "out_collection_name" } )

db.user.mapReduce(
    function(){ emit( key , value ) },
    function( key , values ){},
    { out : "collection" }
)

示例:

var map = function() {
    emit( this.name , { count : 1 } );
}

var reduce = function( key , values ) {
    var result = { count : 0 };
    for(var i = 0; i < values.length; i++ ) {
        result.count += values[i].count;
    }
    return result;
}

db.user.mapReduce(
    map ,
    reduce ,
    { out : "collection" }
)

db.collection.find()

这里写图片描述

解析:

  • map:这个称为映射函数,里面会调用 emit(key,value),集合会按照你指定的 key 进行映射分组。
  • reduce:这个称为简化函数,会对map 分组后的数据进行分组简化,注意:在reduce(key,value) 中的 key 就是 emit 中的 key,vlaue 为 emit 分组后的 emit(value) 的集合,这里也就是很多 {“count”:1} 的数组。
  • mapReduce : 这个就是最后执行的函数了,参数为map,reduce和一些可选参数。具体看图可知。
  • finalize = function(key, return_value) {} 这个函数,每一组文档执行完后,都会触发此方法。在这个方法中可以对 return_value 进行处理。

这个方法执行之后会创建一个名为 collection 的集合。这个方法很复杂,一般不懂就不要用了。另外执行结果信息解释如下:

  • result: “存放的集合名”
  • input:传入文档的个数
  • emit:此函数被调用的次数
  • reduce:此函数被调用的次数
  • output:最后返回文档的个数

runCommand( )

db.runCommand( command )

其中 command 可以是一个 document 或者 String。是要执行的命令。
示例:

/* 来自官网 */
db.runCommand(
   {
     group:
       {
         ns: 'orders',
         key: { ord_dt: 1, 'item.sku': 1 },
         cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } },
         $reduce: function ( curr, result ) { },
         initial: { }
       }
   }
)

/* 前面的mapReduce */
db.runCommand({
    mapreduce : "user",
    map : map,
    reduce : reduce,
    out : "out_user"
})

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值