获取原始文档字段作为聚合结果的一部分

时间:2014-08-03 20:47:44

标签: mongodb aggregation-framework

我想在我的聚合结果中获取所有文档字段,但是一旦我使用$ group,它们就会消失。使用$ project允许我读取我在$ group中定义的任何字段,但在获取其他字段方面没有运气:

var doc = {
  _id: '123',
  name: 'Bob',
  comments: [],
  attendances: [{
    answer: 'yes'
  }, { 
   answer: 'no'
  }]       
}

aggregate({
    $unwind: '$attendances'
  }, {
    $match: {
      "attendances.answer": { $ne:"no" }
    }
  }, {
    $group: {
    _id: '$_id',
    attendances: { $sum: 1 },
    comments: {  $sum: { $size: { $ifNull: [ "$comments", [] ] }}}
  } 
}, {
  $project: {
    comments: 1,
  }
}

这导致:

[{
  _id: 5317b771b6504bd4a32395be,
  comments: 12 
},{
  _id: 53349213cb41af00009a94d0,
  comments: 0 
}]

我如何获得'名字'?我已经尝试将$ group添加为:

name: '$name'

以及$ project:

name: 1

但两者都不会起作用

1 个答案:

答案 0 :(得分:7)

您无法投影在$group操作期间删除的字段。

由于您按原始文档_id进行分组,并且只有一个name值,因此您可以使用$first保留name字段:

db.sample.aggregate(
    { $group: {
        _id: '$_id',
        comments: {  $sum: { $size: { $ifNull: [ "$comments", [] ] }}},
        name: { $first: "$name" }
    }}
)

示例输出将是:     {“_ id”:“123”,“comments”:0,“name”:“Bob”}

如果您按标准进行分组,可以保留多个值,则$group中的数组应$push,如果只需要唯一名称,则应使用$addToSet

投影所有字段

如果您正在使用MongoDB 2.6并希望获得所有原始文档字段(不仅仅是name)而不单独列出它们,则可以使用聚合变量$$ROOT代替特定的字段名称。