具有多个查找和管道的聚合仅返回最后一个元素

Posted

技术标签:

【中文标题】具有多个查找和管道的聚合仅返回最后一个元素【英文标题】:Aggregate with multiple lookup and pipeline return only the last element 【发布时间】:2021-08-16 11:54:47 【问题描述】:

我尝试下面的代码,它正在从其他集合中查找值。但是为什么它只返回最后一个元素。

如果我省略了 unwind 函数,它确实会返回模型的所有结果,但第二次查找不会像第一次查找返回数组那样工作。

我的目标是查找包含在 templatefolders 集合中表示的模型 ID 的文件夹。

const result = await this.dashboardModel
      .aggregate([ $match: filter ])
      .lookup(
        from: 'templatefolders',
        as: 'template',
        let:  id: '$_id' ,
        pipeline: [
          
            $match: 
              $expr: 
                $and: [
                  
                    $eq: ['$dashboardId', '$$id'],
                  ,
                  
                    $eq: ['$deletedAt', null],
                  ,
                ],
              ,
            ,
          ,
          
            $project: 
              _id: 1,
              folderId: 1,
            ,
          ,
        ],
      )
      .unwind('template')
      .lookup(
        from: 'folders',
        as: 'folder',
        let:  folderId: '$template.folderId' ,
        pipeline: [
          
            $match: 
              $expr: 
                $and: [
                  
                    $eq: ['$_id', '$$folderId'],
                  ,
                  
                    $eq: ['$deletedAt', null],
                  ,
                ],
              ,
            ,
          ,
          
            $project: 
              _id: 1,
              name: 1,
            ,
          ,
        ],
      )
      .unwind('folder')
      .exec();
    return result;

结果


  "data": [
    
      ...(parent field)
      "template": 
        "_id": "60ab22b03b39e40012b7cc4a",
        "folderId": "60ab080b3b39e40012b7cc41"
      ,
      "folder": 
        "_id": "60ab080b3b39e40012b7cc41",
        "name": "Folder 1"
      
    
  ],
  "meta": ,
  "success": true,
  "message": "Succesfully get list"

我来自前端背景。我希望我的问题不是愚蠢的。

谢谢!

编辑:

dashboard: [
  _id: dashboard1
]

templatefolders: [
  dashboardId: dashboard1,
  folderId: folder123
]

folders: [
  _id: folder123
]

【问题讨论】:

$unwind 正在解构您的阵列。检查这里mongoplayground.net/p/8KzJs1EneYe 你有一个数组,但展开使其成为 3 个对象。所以当你展开时,你会得到对象,所以展开的结果会改变。在上一阶段的基础上,你需要编写查询。 这里,没有样本数据,我们什么也不能告诉你。如果您需要,请编辑问题并使用仅包含必要字段的示例数据进行更新。 @varman 如何将结果作为包含所有元素的数组再次返回? 您需要使用$group,这有助于再次对对象进行分组 @varman 我添加了一些示例数据。够了吗?我想要实现的是在访问仪表板集合时获取文件夹对象。 【参考方案1】:

您可以使用$lookup加入收藏

$lookup 加入两个收藏 .Lookup doc $unwind 解构数组。 Unwind doc $group 重构我们已经解构的数组 Group doc

这里是代码

db.dashboard.aggregate([
  
    "$lookup": 
      "from": "templatefolders",
      "localField": "_id",
      "foreignField": "dashboardId",
      "as": "joinDashboard"
    
  ,
  
    "$unwind": "$joinDashboard"
  ,
  
    "$lookup": 
      "from": "folders",
      "localField": "joinDashboard.folderId",
      "foreignField": "_id",
      "as": "joinDashboard.joinFolder"
    
  ,
  
    "$group": 
      "_id": "$_id",
      "joinDashboard": 
        "$push": "$joinDashboard"
      
    
  
])

工作Mongo playground

【讨论】:

如果我们想总结一个字段,需要分组吗?我认为我在这个过程中不需要那个 当你展开一个数组时,它会被解构。如果需要重构,则需要对其进行分组。否则它会给出一些重复的条目。但这取决于您的要求!

以上是关于具有多个查找和管道的聚合仅返回最后一个元素的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Mongodb 聚合管道文档返回到一个文档?

正在加载的管道仅返回列名

翻译MongoDB指南/聚合——聚合管道

使用聚合管道聚合 MongoDB 中的时间戳集合

MongoDB,分组,聚合

mongodb 分组聚合查询