使用 mongodb 以特定格式查找和组合数据

Lookup and combine data in a specific format with mongodb

执行查找并将其与用于查找的对象组合的最佳方法是什么?

例如,我有以下格式的集合 1:

{
  _id:ObjectID("xxxxxxxx"),
  id: "12345",
  name: "name xyz",
  goal: "goal 123",
  start: null,
  end: null,
  plan:[
    {
      day: 0,
      exercises:[
        {
          id: "xxxx1",
          stat1: "stat 1 stuff",
          stat2: "stat 2 stuff"
        },
        {
          id: "xxxx2",
          stat1: "stat 1 stuff",
          stat2: "stat 2 stuff"
        }
      ]
    },
    {
      day: 1,
      exercises:[
        {
          id: "xxxx2",
          stat1: "stat 1 stuff",
          stat2: "stat 2 stuff"
        }
      ]
    }
  ]
}

我有集合 2(练习),格式如下:

{
  _id: ObjectID("yyyyyy"),
  id: "xxxx1",
  stat3: "stat 3 stuff",
  stat4: "stat 4 stuff"
},
{
  _id: ObjectID("yyyyyy"),
  id: "xxxx2",
  stat3: "stat 3 stuff",
  stat4: "stat 4 stuff"
}

有没有一种方法可以执行查找并获得以下格式的结果:

{
  _id:ObjectID("xxxxxxxx"),
  id: "12345",
  name: "name xyz",
  goal: "goal 123",
  start: null,
  end: null,
  plan:[
    {
      day: 0,
      exercises:[
        {
          id: "xxxx1",
          stat1: "stat 1 stuff",
          stat2: "stat 2 stuff",
          stat3: "stat 3 stuff",
          stat4: "stat 4 stuff"
        },
        {
          id: "xxxx2",
          stat1: "stat 1 stuff",
          stat2: "stat 2 stuff",
          stat3: "stat 3 stuff",
          stat4: "stat 4 stuff"
        }
      ]
    },
    {
      day: 1,
      exercises:[
        {
          id: "xxxx2",
          stat1: "stat 1 stuff",
          stat2: "stat 2 stuff",
          stat3: "stat 3 stuff",
          stat4: "stat 4 stuff"
        }
      ]
    }
  ]
}

这是您可以做到的一种方法。

db.clients.aggregate([
  {  // lookup from exercises with matching id's
    "$lookup": {
      "from": "exercises",
      "localField": "plan.exercises.id",
      "foreignField": "id",
      "pipeline": [ { "$unset": "_id" } ],  // don't need _id
      "as": "exLookup"
    }
  },
  {  // extend plan with info from lookup
    "$set": {
      "plan": {
        "$map": {  // cycle through each plan array element
          "input": "$plan",
          "as": "planElem",
          "in": {
            "$mergeObjects": [  // keep fields and merge elements
              "$$planElem",  // keep current array element ...
              {              // and merge new fields
                "exercises": {
                  "$map": {  // cycle through each exercises array element
                    "input": "$$planElem.exercises",
                    "as": "exElem",
                    "in": {
                      "$mergeObjects": [  // keep fields and merge elements
                        "$$exElem",  // current array element
                        {
                          "$arrayElemAt": [  // get correct array element ...
                            "$exLookup",     // from lookup
                            { "$indexOfArray": [ "$exLookup.id", "$$exElem.id" ] }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  { "$unset": "exLookup" }  // don't need this anymore
])

mongoplayground.net 上试用。