项目双重嵌套数组MongoDB

4
{
    _id: 'uniquewId',
    programs: [
        {
            progress: '5',
            addedBy: 'coach'
            exercises: [
                {
                     date: '1/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5
                         },
                         {
                              exId: 'situp',
                              progress: 5
                         },
                         {
                              exId: 'pushup',
                              progress: 0
                         }
                     ] 
                },
                {
                    date: '2/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5
                         },
                         {
                              exId: 'situp',
                              progress: 5
                         },
                         {
                              exId: 'pushup',
                              progress: 0
                         }
                     ] 
                }   
            ]
        },
        {
            progress: '5',
            addedBy: 'coach2'
            exercises: [
                {
                     date: '1/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5
                         },
                         {
                              exId: 'situp',
                              progress: 5
                         },
                         {
                              exId: 'pushup',
                              progress: 0
                         }
                     ] 
                },
                {
                    date: '2/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5
                         },
                         {
                              exId: 'situp',
                              progress: 5
                         },
                         {
                              exId: 'pushup',
                              progress: 0
                         }
                     ] 
                }   
            ]
        }
    ]
}

以上是我的文档外观。有没有办法我可以展示程序数组,以便它包含addedBy = 'coach'的文档,并且练习数组内的练习数组应该只有exId ='pushup'

我想要的输出结果是:

{
    _id: 'uniquewId',
    programs: [
        {
            progress: '5',
            addedBy: 'coach'
            exercises: [
                {
                     date: '1/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5
                         },
                         {
                              exId: 'pushup',
                              progress: 0
                         }
                     ] 
                },
                {
                    date: '2/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5
                         },
                         {
                              exId: 'pushup',
                              progress: 0
                         }
                     ] 
                }   
            ]
        }
    ]
}

该程序数组可能有多个文档,这些文档的addedBy='coach'。如果是这样,所有这些文档都应该在那里 :)
2个回答

2

使用双重$map$filter将解决问题:

db.collection.aggregate([
    {
        $project: {
            _id: 1,
            programs: {
                $map: {
                    input: { $filter: { input: "$programs", cond: { $eq: [ "$$this.addedBy", "coach" ] } } },
                    in: {
                        progress: "$$this.progress",
                        addedBy: "$$this.addedBy",
                        exercises: {
                            $map: {
                                input: "$$this.exercises",
                                in: {
                                    date: "$$this.date",
                                    exercises: {
                                        $filter: {
                                            input: "$$this.exercises",
                                            as: "e",
                                            cond: {
                                                $eq: [ "$$e.exId", "pushup" ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
])

Mongo Playground


1
我认为仅靠投影本身无法帮助您实现所描述的结果。请尝试以下方法:
db.collection.aggregate([
  {
    $unwind: "$programs"
  },
  {
    $match: {
      "programs.addedBy": "coach"
    }
  },
  {
    $project: {
      programs: {
        progress: "$programs.progress",
        addedBy: "$programs.addedBy",
        exercises: {
          $map: {
            input: "$programs.exercises",
            as: "exercise",
            in: {
              date: "$$exercise.date",
              exercises: {
                $filter: {
                  input: "$$exercise.exercises",
                  as: "exerciseDetails",
                  cond: {
                    $eq: [
                      "$$exerciseDetails.exId",
                      "pushup"
                    ]
                  }
                }
              }
            }
          },

        }
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      programs: {
        $push: "$programs"
      }
    }
  }
])

为什么这样做可以成功:

以上是聚合以获得所述输出的过程。我在管道中使用了4个聚合阶段和几个聚合运算符。这些阶段是:

  • $unwind - 这有助于将程序数组扩展,以便每个程序都有一个文档,这使得处理每个程序内部嵌套的练习数组变得容易。
  • $match - 这有助于过滤掉“教练”未添加的程序。
  • $project - 这基本上是向前投射数据,同时使用聚合运算符对一些输入数据进行转换。我在“program.exercises”上使用了$map运算符,以访问练习数组中的每个练习。在每个练习对象中,我使用$filter运算符来删除其exId不是“pushup”的练习。
  • $group - 这只是我先前所做的$unwind的清理工作,它将最初在管道开头扩展的程序重新分组。
你可以在这个playground中测试它。保留html,不要解释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接