【问题标题】:Project double nested array mongodb项目双嵌套数组mongodb
【发布时间】:2020-03-27 01:52:48
【问题描述】:
{
    _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',如果是这样,它应该都在那里:)

【问题讨论】:

    标签: node.js mongodb aggregation-framework


    【解决方案1】:

    $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

    【讨论】:

      【解决方案2】:

      我不认为仅靠投影可以帮助您实现您所描述的结果。试试这个:

      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中测试一下

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-11
        • 2019-12-07
        • 2013-08-10
        • 2015-05-18
        • 2020-10-22
        • 2017-09-30
        • 1970-01-01
        相关资源
        最近更新 更多