【问题标题】:MongoDB: aggregate lookup in deeply nested array of objectsMongoDB:在深度嵌套的对象数组中进行聚合查找
【发布时间】:2021-01-18 11:06:10
【问题描述】:

我有两个收藏:

音频

[
       {
        "_id": "5f6b1a2e69eef14818ca03a7",
        "audioURL": "https://boyd.org",
        "state": "draft",
       }
       {
        "_id": "5f6b1e1c6297f34bc6f1fee3",
        "name": "navigate",
        "audioURL": "http://mariane.org",
        "state": "draft",
       },
       {
        "_id": "5f5b5423ba39f738d593b504",
        "audioURL": "https://storage/test123mp31599820832928.mp3",
        "state": "draft",
       }
]

课程:

 "lessons": [
  {
   "_id": "5f770e275cef7a611f3cf931",
   "minigameDescriptions": [
    {
     "assessmentSections": [
      {
       "mark": "step_1",
       "start": 1,
       "end": 2,
       "stepAudio": {
        "backingTrackAudioId": "5f6b1a2e69eef14818ca03a7",
        "previewTrackAudioId": "5f6b1a2e69eef14818ca03a7"
       }
      },
      {
       "mark": "step_2",
       "start": 3,
       "end": 6,
       "stepAudio": {
        "backingTrackAudioId": "5f6b1e1c6297f34bc6f1fee3",
        "previewTrackAudioId": "5f6b1e1c6297f34bc6f1fee3"
       }
      },
      {
       "mark": "step_3",
       "start": 7,
       "end": 10,
       "stepAudio": {
        "backingTrackAudioId": "5f6b1a2e69eef14818ca03a7",
        "previewTrackAudioId": "5f5b5423ba39f738d593b504"
       }
      }
     ],
     "drumStyleName": "DrumStyleHalftimeShuffle",
     "onboarding": false,
     "showHints": false,
     "minigameType": "StrummingTrainer",
    }
   ],
   "_updated_at": "2020-10-02T12:00:23.848Z",
  }
 ]
}

现在我必须汇总它,因为在每个 mingameDescriptions.assessmentSections 中都有属性 stepAudio 具有 previewTrackAudioIdbackingTrackAudioId。这些对集合“音频”的引用,我需要将它们作为对象加入其中(音频主键是_id)。我已经尝试过以下管道(现在我只尝试查找 previewTrackAudio ):

{
        $unwind: {
          path: "$minigameDescriptions.assessmentSections",
          preserveNullAndEmptyArrays: true
        },
      },
      {
        $lookup: {
          from: "audios",
          let: {
            audioId: "$minigameDescriptions.assessmentSections.stepAudio.previewTrackAudioId"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $eq: ["$_id", "$$audioId"]
                }
              }
            }
          ],
          as: "minigameDescriptions.assessmentSections.stepAudio.previewTrackAudio"
        }
      },
      {
        $unwind: {
          preserveNullAndEmptyArrays: true,
          path: "$minigameDescriptions.assessmentSections.stepAudio.previewTrackAudio"
        }
      }

它“有点”有效,我得到以下结果:

{
 "lessons": [
  {
   "_id": "5f770e275cef7a611f3cf931",
   "minigameDescriptions": [
    {
     "assessmentSections": {
      "mark": "step_2",
      "start": 3,
      "end": 6,
      "stepAudio": {
       "backingTrackAudioId": "5f6b1e1c6297f34bc6f1fee3",
       "previewTrackAudioId": "5f6b1e1c6297f34bc6f1fee3",
       "previewTrackAudio": {
        "_id": "5f6b1e1c6297f34bc6f1fee3",
        "name": "navigate",
        "audioURL": "http://mariane.org",
        "state": "draft",
       }
      }
     },
     "drumStyleName": "DrumStyleHalftimeShuffle",
     "onboarding": false,
     "showHints": false,
     "minigameType": "StrummingTrainer",
    },
    {
     "assessmentSections": {
      "mark": "step_3",
      "start": 7,
      "end": 10,
      "stepAudio": {
       "backingTrackAudioId": "5f6b1a2e69eef14818ca03a7",
       "previewTrackAudioId": "5f5b5423ba39f738d593b504",
       "previewTrackAudio": {
        "_id": "5f5b5423ba39f738d593b504",
        "audioURL": "https://storage/test123mp31599820832928.mp3",
        "state": "draft",
       }
      }
     },
     "drumStyleName": "DrumStyleHalftimeShuffle",
     "onboarding": false,
     "showHints": false,
     "minigameType": "StrummingTrainer",
    },
    {
     "assessmentSections": {
      "mark": "step_1",
      "start": 1,
      "end": 2,
      "stepAudio": {
       "backingTrackAudioId": "5f6b1a2e69eef14818ca03a7",
       "previewTrackAudioId": "5f6b1a2e69eef14818ca03a7",
       "previewTrackAudio": {
        "_id": "5f6b1a2e69eef14818ca03a7",
        "audioURL": "https://boyd.org",
        "state": "draft",
       }
      }
     },
     "drumStyleName": "DrumStyleHalftimeShuffle",
     "onboarding": false,
     "showHints": false,
     "minigameType": "StrummingTrainer",
    }
   ],
   "_updated_at": "2020-10-02T12:00:23.848Z",
  }
 ]
}

但是现在我没有一个包含 3 个 mingameDescriptions.assessmentSections 的数组,而是一个包含三个对象的数组,这些对象具有 assesmentSections 以及来自 minigameDescriptions 的重复属性,这是错误的:/。我该如何解决这个问题?

我想得到的是:

 "lessons": [
  {
   "_id": "5f770e275cef7a611f3cf931",
   "minigameDescriptions": [
    {
     "assessmentSections": [
      {
       "mark": "step_1",
       "start": 1,
       "end": 2,
       "stepAudio": {
        "backingTrackAudioId": "5f6b1a2e69eef14818ca03a7",
        "previewTrackAudioId": "5f6b1a2e69eef14818ca03a7",
        "previewTrackAudio": {
         "_id": "5f6b1a2e69eef14818ca03a7",
         "audioURL": "https://boyd.org",
         "state": "draft",
        }
       }
      },
      {
       "mark": "step_2",
       "start": 3,
       "end": 6,
       "stepAudio": {
        "backingTrackAudioId": "5f6b1e1c6297f34bc6f1fee3",
        "previewTrackAudioId": "5f6b1e1c6297f34bc6f1fee3",
        "previewTrackAudio": {
          "_id": "5f5b5423ba39f738d593b504",
          "audioURL": "https://storage/test123mp31599820832928.mp3",
          "state": "draft",
         }
       }
      },
      {
       "mark": "step_3",
       "start": 7,
       "end": 10,
       "stepAudio": {
        "backingTrackAudioId": "5f6b1a2e69eef14818ca03a7",
        "previewTrackAudioId": "5f5b5423ba39f738d593b504",
        "previewTrackAudio": {
         "_id": "5f5b5423ba39f738d593b504",
         "audioURL": "https://storage/test123mp31599820832928.mp3",
         "state": "draft",
        }
       }
      }
     ],
     "drumStyleName": "DrumStyleHalftimeShuffle",
     "onboarding": false,
     "showHints": false,
     "minigameType": "StrummingTrainer",
    }
   ],
   "_updated_at": "2020-10-02T12:00:23.848Z",
  }
 ]
}

【问题讨论】:

  • 您需要同时发布这两个集合。并且不要发布不必要的字段,这会让其他人在查看时感到不舒服
  • 对,我已经发布了两个集合并删除了不必要的字段。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

你的尝试是正确的。

[
  {
    $unwind: "$minigameDescriptions"
  },
  {
    $unwind: "$minigameDescriptions.assessmentSections"
  },
  {
    $lookup: {
      from: "Audios",
      let: {
        audioId: "$minigameDescriptions.assessmentSections.stepAudio.previewTrackAudioId"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: [
                "$_id",
                "$$audioId"
              ]
            }
          }
        }
      ],
      as: "minigameDescriptions.assessmentSections.stepAudio.previewTrackAudio"
    }
  },
      {
    $group: {
      _id: {
        _id: "$_id",
        /**   assId: "$minigameDescriptions.assessmentSections.mark"*/
        
      },
      assessmentSections: {
        $addToSet: "$minigameDescriptions.assessmentSections"
      },
      drumStyleName: {
        $first: "$minigameDescriptions.drumStyleName"
      },
      minigameType: {
        $first: "$minigameDescriptions.minigameType"
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      minigameDescriptions: {
        $addToSet: {
          assessmentSections: "$assessmentSections",
          drumStyleName: "$drumStyleName",
          minigameType: "$minigameType"
        }
      }
    }
  }
]

工作Mongo playground

注意:这里我们做了两次展开,所以最好进行分组操作。小心,我在第一组中评论了assessmentId,这在您的文档中不存在。但最好有任何东西来识别assessmentSections 中的每个元素,这有助于不复杂

【讨论】:

  • 这几乎是我需要的,谢谢!我已经编辑了帖子以添加我需要的响应,因为在您的解决方案中我只得到assessmentSections,而minigameDescriptions 的其余属性丢失了。你能帮我解决这个问题吗?
  • 我已经更新了我对几个领域所做的回答,你可以按照同样的方式进行
  • 这对你有帮助吗?
  • 稍后我会检查并通知您!
猜你喜欢
  • 2020-01-24
  • 2021-06-03
  • 1970-01-01
  • 2018-09-10
  • 2023-01-12
  • 2020-12-18
  • 2021-08-13
  • 1970-01-01
  • 2018-11-17
相关资源
最近更新 更多