【问题标题】:MongoDB Aggregation Multiple KeysMongoDB聚合多键
【发布时间】:2013-07-16 00:27:18
【问题描述】:

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

{
  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}”?感谢您的回复。

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:

    mapReduce 可以用来解决这个问题。

    1) 定义如下map函数

    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
          }
       }
    }
    

    您可以轻松自定义。

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

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

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

      分组后,你可以随意投影

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多