Проект из двойного вложенного массива путем проверки значения внутри массива Mongodb - PullRequest
1 голос
/ 29 марта 2020
{
    _id: 'uniquewId',
    programs: [
        {
            prgName: 'prgOne',
            progress: '5',
            addedBy: 'coach'
            exercises: [
                {
                     date: '1/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: true
                                  },
                                  {
                                     id: 'myId2',
                                     done: false
                                  } 
                              ]
                         },
                         {
                              exId: 'situp',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: true
                                  },
                                  {
                                     id: 'myId2',
                                     done: true
                                  } 
                              ]
                         }
                     ] 
                },
                {
                    date: '2/12/20',
                    exercises: [
                         {
                              exId: 'pushup',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: true
                                  },
                                  {
                                     id: 'myId2',
                                     done: false
                                  } 
                              ]
                         },
                         {
                              exId: 'situp',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: fase
                                  },
                                  {
                                     id: 'myId2',
                                     done: false
                                  } 
                              ]
                         }
                     ] 
                }   
            ]
        },
        {
            prgName: 'prgTwo',
            progress: '5',
            addedBy: 'coach2'
            exercises: [
                 {
                     date: '1/12/20',
                     exercises: [
                         {
                              exId: 'pushup',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: true
                                  },
                                  {
                                     id: 'myId2',
                                     done: true
                                  } 
                              ]
                         },
                         {
                              exId: 'situp',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: false
                                  },
                                  {
                                     id: 'myId2',
                                     done: false
                                  } 
                              ]
                         }
                     ] 
                },
                {
                    date: '2/12/20',
                    exercises: [
                         {
                              exId: 'pushup',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: true
                                  },
                                  {
                                     id: 'myId2',
                                     done: false
                                  } 
                              ]
                         },
                         {
                              exId: 'situp',
                              progress: 5,
                              attributes: [
                                  {
                                     id: 'myId',
                                     done: true
                                  },
                                  {
                                     id: 'myId2',
                                     done: false
                                  } 
                              ]
                         }
                     ] 
                }   
            ]
        }
    ]
}

Это выше структура моего документа. То, что я хочу сделать, это из массива программ, который я хочу спроецировать с именем упражнений, у которых есть только один документ в массиве атрибутов, в котором ключ помечен как истинный. То, что я пытаюсь сделать, это выяснить упражнения, которые выполнили значение true в массиве атрибутов
Есть ли какой-нибудь способ, которым я могу получить вывод как:

{
    _id: 'uniquewId',
    programs: [
        {
            prgName: 'prgOne',
            exercises: [
                'pushup',
                'situp'  
            ]  
        },
        {
            prgName: 'prgTwo',
            exercises: [
                'pushup',
                'situp'  
            ]  
        }
    ]
}

1 Ответ

1 голос
/ 29 марта 2020

Это утомительный процесс .

С оператором $ map мы можем перебирать массивы. Также $map позволяет преобразовывать массив объектов в массив строк.

[{k1:v1}, {k2:v2}, ...] -> [v1, v2, ...]

Псевдокод

1-й шаг . Мы выполняем комплексное агрегирование и предварительно вычисляем значения

for (Programs program: doc.programs) {
    return {
        prgName : program.prgName,
        exercises : [
            for (Exercises exer1: program.exercises) {
                for (Exercises exer2: exer1.exercises) {
                    return {
                        exId : exer2.exId,
                        done : exer2.attributes.done.contains(true)
                    }
                }
            }
        ]
    }
}

2-й шаг . Построим желаемый результат


db.collection.aggregate([
  {
    $project: {
      programs: {
        $map: {
          input: "$programs",
          as: "program",
          in: {
            prgName: "$$program.prgName",
            exercises: {
              $reduce: {
                input: {
                  $map: {
                    input: "$$program.exercises",
                    as: "exer1",
                    in: {
                      $map: {
                        input: "$$exer1.exercises",
                        as: "exer2",
                        in: {
                          exId: "$$exer2.exId",
                          done: {
                            $in: [
                              true,
                              "$$exer2.attributes.done"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                initialValue: [],
                in: {
                  $concatArrays: [
                    "$$value",
                    "$$this"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $project: {
      programs: {
        $map: {
          input: "$programs",
          as: "program",
          in: {
            prgName: "$$program.prgName",
            exercises: {
              $reduce: {
                input: {
                  $filter: {
                    input: "$$program.exercises",
                    cond: {
                      $eq: [
                        "$$this.done",
                        true
                      ]
                    }
                  }
                },
                initialValue: [],
                in: {
                  $concatArrays: [
                    "$$value",
                    {
                      $cond: [
                        {
                          $in: [
                            "$$this.exId",
                            "$$value"
                          ]
                        },
                        [],
                        [
                          "$$this.exId"
                        ]
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
])

MongoPlayground

...