MongoDB聚合`$ group`:指定默认的运算符?

时间:2018-09-08 09:12:08

标签: mongodb aggregation-framework

我正在聚合管道中执行$group,其中我将$push的一个属性添加到数组,而对于所有其余属性,我只需要使用$first

{ $group: { 
  '_id': '$_id', 
  property1: { $push: '$property1' }, 
  property2: { $first: '$property2' }, 
  property3: { $first: '$property3' }, 
  property4: { $first: '$property4' }, 
  property5: { $first: '$property5' }, 
  property6: { $first: '$property6' }, 
  property7: { $first: '$property7' }, 
  // …
}},

是否有可能以更简洁的方式进行指定?我希望以下内容(不起作用)表示“ $push使用property1,其他任何内容使用$first

{ $group: { 
  '_id': '$_id', 
  property1: { $push: '$property1' }, 
  '*': { $first: '$*' }
}},

2 个答案:

答案 0 :(得分:1)

不,没有其他办法。您必须在$first阶段使用$group累加器指定每个字段。

但是您可以避免为每个字段指定$first。像这样

{ "$group": { 
  "_id": "$_id", 
  "property1": { "$push": "$property1" }, 
  "data": {
    "$first": {
      "property2": "$property2", 
      "property3": "$property3", 
      "property4": "$property4", 
      "property5": "$property5", 
      "property6": "$property6", 
      "property7": "$property7"
    }
  }
}}

答案 1 :(得分:1)

如上所述,安东尼·温兹莱特(Anthony Winzlet)无法通过$group运算符来实现这一目标。但是,我使用了以下解决方法,这使我不必显式列出所有这些属性。拥有少量属性可能不值得麻烦,如果您不需要照顾灵活性,可以稍后再添加其他属性,但就我而言,这是有道理的。

这里是聚合管道的想法:

  1. 使用$addFields将整个根文档添加为临时副本。
  2. 指定分组阶段,在其中添加所需属性的$push,对于以前复制的整个子文档,请使用$first运算符。
  3. 使用$replaceRoot$mergeObjects来获取复制的根文档,并将属性替换为$push聚合。

这是一个例子:

db.getCollection('test').aggregate([
  { $addFields: { tempRoot: '$$ROOT' } },
  { $group: { '_id': '$property1', 'property2': { $push: '$property2' }, 'tempRoot': { $first: '$tempRoot' } } },
  { $replaceRoot: { newRoot: { $mergeObjects: [ '$tempRoot', { property2: '$property2' } ] } } }
]);