1

部門とステータスを使用して従業員を集計し、各ステータスの合計を計算しようとしています。これから:

{
  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}」を正しく配置するには? ご回答ありがとうございます。

4

2 に答える 2

1

可能なステータスが存在するか存在しないかだけの場合、$cond演算子を$eq演算子と組み合わせて使用​​できます。

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

グループ化した後、必要に応じて投影できます

于 2013-07-17T14:06:57.673 に答える
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
      }
   }
}

簡単にカスタマイズできること。

お役に立てば幸いです。

于 2013-07-17T13:40:44.163 に答える