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

cyb*_*bat 5 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,
  }
}
Run Code Online (Sandbox Code Playgroud)

这导致:

[{
  _id: 5317b771b6504bd4a32395be,
  comments: 12 
},{
  _id: 53349213cb41af00009a94d0,
  comments: 0 
}]
Run Code Online (Sandbox Code Playgroud)

我怎么在那里得到'名字'?我尝试将$ group添加为:

name: '$name'
Run Code Online (Sandbox Code Playgroud)

以及在$ project中:

name: 1
Run Code Online (Sandbox Code Playgroud)

但两者都不会起作用

Ste*_*nie 7

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

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

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

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

如果按标准对可能存在多个值的条件进行分组,则应该使用或者使用$push数组,如果只需要唯一名称.$group$addToSet

投射所有领域

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

  • @yashua:`$ group`聚合结合了多个文档的值,因此您必须对多个名称字段执行某些操作.您可以使用`$ first`将列表中的第一个名称作为字符串,但我认为您所追求的只是JohnnyHK建议的'$ project`.您的实际用例是否比问题描述中发布的更复杂? (2认同)