如何使用带有_id数组的动态集合的聚合来获取数据

Posted

技术标签:

【中文标题】如何使用带有_id数组的动态集合的聚合来获取数据【英文标题】:how to fetch data using aggregate with dynamic collection with array of _id's 【发布时间】:2019-10-19 16:42:13 【问题描述】:

我需要从动态集合中获取数据,例如 if type = category 然后从类别集合中获取数据 if type = banner 从横幅中获取数据。

输入数据数组:

[
 
  "title": "New Product",
  "row_data": [
   
    "type": "category",
    "data": [
      5cf4edcdc70d4716d821d45d,5cf4ee36c70d4716d821d460
    ]
   ,
   
    "type": "banner",
    "data": [
     5ce4eb55b02bd01ca09eb909
    ]
   ,
   
    "type": "product",
    "data": [
     5cf4eed8c70d4716d821d465,5cf4fa09c70d4716d821d483
    ]
   
  ],
  "_id": "5cf611c7fcc98b16b0e89200"
 
]

预期输出数组:

[
 
  "title": "New Product",
  "row_data": [
   
    "type": "category",
    "data": [_id: 5cf4edb7c70d4716d821d45c, image: "image.jpg", title: "Saree",_id: 5cf4edcdc70d4716d821d45d, image: "image.jpg", title: "Kurti"]
   ,
   
    "type": "banner",
    "data": [_id: 5ce4eb55b02bd01ca09eb909, name: "first banner", image: "banner-image.jpg"]
   ,
   
    "type": "product",
    "data": [_id: 5cf4eed8c70d4716d821d465, image: "image.jpg", sku: "S-01",_id: 5cf4fa09c70d4716d821d483, image: "image.jpg", sku: "K-01"]
   
  ],
  "_id": "5cf611c7fcc98b16b0e89200"
 
]

【问题讨论】:

【参考方案1】:

您可以做的最好的事情是使用$facet 将其拆分为几个不同的聚合,然后将它们“合并”回所需的结构。

看起来有点像这样:


   $unwind: "$row_data"
,   

  $facet: 
     categories: [
         $lookup:
           from: "categories",
           let:  ids: "$row_data.data",
           pipeline: [
               $match:
                  $expr:
                     
                        $in: ["$_id", "$$ids"]
                    
                 
              ,
           ],
           as: "match"
         ,
         
           $match: 
              'match.0': $exists: true
            
         ,
         
            $addFields: 
                 temp: type: 'category', data: '$match'
            
        
     ],
     banners: [
         $lookup:
           from: "banner",
           let:  ids: "$row_data.data",
           pipeline: [
               $match:
                  $expr:
                     
                        $in: ["$_id", "$$ids"]
                    
                 
              ,
           ],
           as: "match"
         ,
         
           $match: 
              'match.0': $exists: true
            
        ,
        
            $addFields: 
                 temp: type: 'banner', data: '$match'
            
        
     ],
     ....
  
,

  $addFields: 
    "merged":  $concatArrays: [ "$categories", "$banners", ...] 
  
,

 $unwind: "$merged"
,

  $group: 
     _id: "$merged._id",
     title: $first: "$merged.title",
     row_data: $push: "$merged.temp"
  

请注意,我试图让这个聚合更具可读性,这意味着它没有尽可能高效。

【讨论】:

以上是关于如何使用带有_id数组的动态集合的聚合来获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何将字段的值聚合到数组中?

使用 pymongo 从多个更高级别的数组对象聚合嵌套数组对象

如何在mongodb聚合中获取数据作为数组

如何聚合 ObjectId 对数组及其相关集合

根据学生 ID 聚合多个集合

Mongodb对来自聚合方面的两个相似数据数组进行分组和求和