2013-12-14 104 views
1

我有点卡在MongoDB的聚合框架中,看起来很简单。Mongo Aggregation分组子文档

想象一下,你有文件,将是这样的:

[ 
    { a: 1, b: 2 }, 
    { a: 1, b: 3 }, 
    { a: 5, b: 6 } 
] 
  • 你怎么能组通过现场a文件,然后由另一场重组子文档,说b同时还计算总数每一步的文件?

在我们的例子中,结果看起来是下面的输出文件:

{ 
    results: [ 
     { 
      _id: { 
       a: 1 
      }, 
      sum_a: 2, 
      doc_a: [ 
       { 
        _id: { 
         b: 2 
        }, 
        sum_b: 1 
       }, 
       { 
        _id: { 
         b: 3 
        }, 
        sum_b: 1 
       } 
      ] 
     }, 
     { 
      _id: { 
       a: 5 
      }, 
      sum_a: 1, 
      doc_a: [ 
       { 
        _id: { 
         b: 6 
        }, 
        sum_b: 1 
       } 
      ] 
     } 
    ] 
} 

我试过这样的事情:

printjson(db.getSiblingDB('mydb').mycollection.aggregate([ 
    { 
     $project: { 
      a: 1, 
      b: 1 
     } 
    }, 
    { 
     $group: { 
      _id: { 
       a: '$a' 
      }, 
      sum_a: { 
       $sum: 1 
      }, 
      b: { 
       $first: '$b' 
      } 
     } 
    }, 
    { 
     $group: { 
      _id: { 
       b: '$b' 
      }, 
      sum_b: { 
       $sum: 1 
      } 
     } 
    }, 
    { 
     $sort: { 
      sum_a: 1 
     } 
    } 
])); 

但在我做出了不同的测试,它使覆盖以前的小组阶段结果,错误地计算总和......等等。

所以我真的不知道如何解决这个问题。

回答

3

如果您将主字段('a')和子字段('b')组合在一起,然后仅对'a'进行分组(将第一步的计数相加)并将'b'推入数组中从第一步复制计数),它应该会产生你所需要的:

{ 
    $group : { 
     _id : { 
      a : '$a', 
      b : '$b' 
     }, 
     count : { 
      $sum : 1 
     } 
    } 
},{ 
    $group : { 
     _id : { 
      a : '$_id.a' 
     }, 
     count_a : {$sum: '$count'}, 
     doc_a : { 
      $push : { 
       b : '$_id.b', 
       count_b : '$count' 
      } 
     } 
    } 
}