如何使用 mongo 聚合管道对 subdoc 数组进行分组和组合

时间:2021-07-06 20:29:01

标签: arrays mongodb mongoose aggregation-framework

设想一个集合,在聚合的 $match 运算符上返回具有此结构的文档数组

A = {
  slug:'a',
  Rs:[{
    _id:'foo',
    attr2:'bar'
  }]
}

所以基本上每个返回的文档都共享一个 slug(这就是我将它们分组的方式)但每个文档都有一个子文档数组,每个子文档都有不同的 _id。

因此,当我使用 {slug:"a"} 执行 $match 聚合时,它会返回一个 [A0,A1,A2...] 等数组,它们共享相同的 slug。我打电话给每个文档 A

接下来在管道中我将它们分组并想查看它们的 Rs 数组

{
 $group:{
    _id:'$slug',
    arrays:{$push:'$rs'}
  } 
}

这将返回一个看起来像这样的文档

{
  _id:"a",
  arrays: [
  [{_id:'foo',attr2:'bar'},{_id:'foo2',attr2:'beer'}], //The arrays of document A0
  [*A1 arrays*], //the arrays of document A1
  [*A2 arrays*]
  ]
}

因此,这是将我的所有文档分组为一个,并将它们的 subdoc 数组作为我的分组文档中的子数组给出,该子数组是一组数组 arrays:[[A0Rs0,A0Rs1],[A1Rs0,A1Rs1],[A2Rs0,etc]]

我的总体目标是合并或展平这些数组,因此我拥有一个包含所有值的单个数组,而不是拥有一个数组数组,并且理想情况下我希望使用聚合运算符来执行此操作。因此,我不会像上面那样以数组数组结尾,而是以

结尾
{
 _id:"a",
 arrays:[
   {},{},{}... //all of the arrays. In fact these dont even have to be objects, I am after just the ID field of each object
 ]
}

我尝试了 $concatArrays 和其他运算符的组合,不确定是否需要在 $group 之前添加其他步骤或聚合器或如何处理。

我希望我的解释不会太混乱,如果有人能想出办法做到这一点,我将非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

如果有人有兴趣了解获得正确解决方案的一种方法,因为我确信不止一种方法,我设法通过使用运算符组合(从 $unwind 开始)获得了我正在寻找的结果。< /p>

$unwind 基本上将您的父文档(带有数组的文档)分成多个文档,数组中的每个元素一个。 IT 会为您的所有结果执行此操作,因此现在您不再拥有多个带有子文档数组的对象,您只需拥有一个带有单个子文档的多个文档。然后你可以使用 $match 和 $group 这样最终你会得到一个包含所有你想要的结果的数组。如果在这种情况下您只需要像我这样的一个数组,您也可以使用 $project 来减少文档中的字段数。