嵌套数组上的猫鼬聚合

Posted

技术标签:

【中文标题】嵌套数组上的猫鼬聚合【英文标题】:mongoose aggregate on a nested array 【发布时间】:2021-04-14 18:35:48 【问题描述】:

我有一个包含子数组的架构,并且它的每个元素都引用另一个架构,如下所示:


 _id: "5fed222d806311ec81d6df23"
 someOtherNestedDoc: 
    _id: "abc",
    someOtherField: 10
 ,
 matches: [
   
      _id: "5fed222d806311ec81d6daf3",
      user: "5fed222d806311ec81d6dcf3",
      probability: 10
   ,
   
      _id: "5fed222d806311ec81d6d1f3",
      user: "5fed222d806311ec81d62cf3",
      probability: 20
   ,
 ]

我想做一个 Mongoose 聚合,在其中我查找每个匹配项的用户引用,并且只为它项目 3 个字段,2 个已经存在,第三个是该模式的数组的总和,所以最后,我有这样的事情:


 _id: "5fed222d806311ec81d6df23"
 someOtherNestedDoc: 
    _id: "abc",
    someOtherField: 10
 ,
 matches: [
   
      _id: "5fed222d806311ec81d6daf3",
      user: 
         firstName: "Max",
         lastName: "Mustermann",
         totalExpenses: 100
      ,
      probability: 10
   ,
   
      _id: "5fed222d806311ec81d6d1f3",
      user: 
         firstName: "Herbert",
         lastName: "Mustermann",
         totalExpenses: 200
      ,,
      probability: 20
   ,
 ]

用户看起来像这样:


  _id: "5fed222d806311ec81d6dcf3",
  firstName: "Max",
  lastName: "Mustermann",
  password: "test",
  expenses: [
    
      _id: 1,
     price: 50
    ,
    
      _id: 2,
     price: 50
    ,
   ]



  _id: "5fed222d806311ec81d62cf3",
  firstName: "Herbert",
  lastName: "Mustermann",
  password: "test2",
  expenses: [ 
    
      _id: 3,
     price: 75
    ,
    
      _id: 4,
     price: 125
    ,
   ]

【问题讨论】:

【参考方案1】: $unwind解构matches数组 $lookup 带有用户集合并在 let 中传递用户 ID, $matchuserId 条件 $project 显示必填字段,得到expenses.price 的总和 $unwind解构user数组 $group by _id 并重构 matches 数组
db.col1.aggregate([
   $unwind: "$matches" ,
  
    "$lookup": 
      "from": "user",
      let:  userId: "$matches.user" ,
      pipeline: [
         $match:  $expr:  $eq: ["$_id", "$$userId"]   ,
        
          $project: 
            _id: 0,
            firstName: 1,
            lastName: 1,
            totalExpenses:  $sum: "$expenses.price" 
          
        
      ],
      "as": "matches.user"
    
  ,
   $unwind: "$matches.user" ,
  
    $group: 
      _id: "$_id",
      matches:  $push: "$matches" 
    
  
])

Playground

【讨论】:

这通常工作得很好,唯一的事情是,如果我在原始文档中除了“匹配”之外还有其他字段,那么这些字段就会丢失。我怎样才能保存这些?我编辑了问题。 你可以使用带有字段名的 $first 运算符看看这个playground

以上是关于嵌套数组上的猫鼬聚合的主要内容,如果未能解决你的问题,请参考以下文章

无法查询嵌套的猫鼬数组?

嵌套数组的猫鼬$或条件

更新混合类型的猫鼬嵌套数组

用于多个对象数组的猫鼬嵌套模式

使用没有数组的嵌套文档为我的 JSON 定义有效的猫鼬模式?

嵌套的猫鼬填充了承诺