MongoDB聚合多个密钥

时间:2013-07-17 12:39:30

标签: mongodb mongoose aggregation-framework

我尝试使用部门和状态汇总员工,以计算每个状态的汇总。由此:

{
  name : "Employee_1",
  department: "hr",
  status : "exist"
},
{
  name : "Employee_2",
  department: "acme",
  status : "absent"
},
{
  name : "Employee_3",
  department: "acme",
  status : "absent"
}
...

到此:

{
  department: "hr",
  statuses: {
    exist: 1,
    absent: 0
  }
},
{
  department: "acme",
  statuses: {
    exist: 0,
    absent: 2
  }
}
...

我试图通过以下方式来实现:

Employee.aggregate(  
        { $group: {
            _id: '$department',
            statuses: { $addToSet: "$status" }
        }},
        { $project: { _id: 1, statuses: 1 }},
        function(err, summary) {
            console.log(summary);
        }
    );

我只获得数组中的状态,由“$ addToSet”生成:

{
  department: "hr",
  statuses: [
      'exist',
      'absent'
  ]
},
{
  department: "acme",
  statuses: [
      'exist',
      'absent'
  ]
}
...

如何为每种状态设置“{$ sum:1}”?谢谢你的回复。

2 个答案:

答案 0 :(得分:1)

mapReduce可用于解决问题。

1)定义以下地图功能

var mapFunction = function() {
  var key = this.department;
  var nb_match_bar2 = 0;
  var status_exist = 0;
  var status_absent = 0;
  if( this.status=="exist" ){
    status_exist = 1;
  }else{
    status_absent= 1;
  }
  var value = {
    department: this.department,
    statuses:{
      exist: status_exist,
      absent: status_absent
    }
  };

  emit( key, value );
};

2)定义reduce函数

var reduceFunction = function(key, values) {

  var reducedObject = {
    department: key,
    statuses: {
      exist: 0,
      absent:0
    }
  };
  values.forEach( function(value) {
    reducedObject.statuses.exist += value.statuses.exist;
    reducedObject.statuses.absent += value.statuses.absent;
  }
  );
  return reducedObject;
};

3)运行mapduce并将结果存储在集合map_reduce_result

db.rien.mapReduce(mapFunction, reduceFunction, {out:'map_reduce_result'})

4)最后,查询集合map_reduce_result

db.map_reduce_result.find()

对于你的收藏,它应该给出类似的东西

{
   "_id" : "acme",
   "value" : {
      "department" : "acme",
      "statuses" : {
         "exist" : 0,
         "absent" : 2
      }
   }
}
{
   "_id" : "hr",
   "value" : {
      "department" : "hr",
      "statuses" : {
         "exist" : 1,
         "absent" : 0
      }
   }
}

您可以轻松自定义。

我希望它有所帮助。

答案 1 :(得分:1)

如果可能的状态存在且不存在,您可以将$cond运算符与$eq运算符结合使用。

{ 
    $group : {
        _id : '$department',
        exist :  { $sum : {  $cond : [ { $eq : ['$status', 'exist'] }  ,1,0 ]  } },
        absent :  { $sum : {  $cond : [ { $eq : ['$status', 'absent'] }  ,1,0 ]  } }
    } 
}

分组后,您可以根据需要进行投影