Home > Blockchain >  Project object from Nested Array MongoDB
Project object from Nested Array MongoDB

Time:03-12

[
  {
    "_id": "grandParentId",
    "types": [
      {
        "_id": "parentId",
        "files": [
          {
            "url": "1.example.com",
            "_id": "1childId"
          },
          {
            "url": "2.example.com",
            "_id": "2childId"
          }
        ]
      }
    ]
  }
]

cond: { _id: 2childId }

expected output: { "url": "2.example.com", "_id": "2childId" }

question 2: is this a good approach or should I just use loops to get the desired output?

CodePudding user response:

useing aggregate $unwind and $project

test it at mongoPlayground

db.collection.aggregate([
  {
    "$unwind": "$types"
  },
  {
    "$unwind": "$types.files"
  },
  {
    "$match": {
      "types.files._id": "2childId"
    }
  },
  {
    "$project": {
      "url": "$types.files.url",
      "_id": "$types.files._id"
    }
  }
])

CodePudding user response:

I'm sure that there are other ways, but you can use mongo aggregation framework:

db.collection.aggregate([
  {
    $match: {
      "types.files._id": "2childId"
    }
  },
  {
    $unwind: "$types"
  },
  {
    $unwind: "$types.files"
  },
  {
    $replaceRoot: {
      newRoot: "$types.files"
    }
  },
  {
    $match: {
      _id: "2childId"
    }
  }
])

The first $match is just to filter documents which match with your condition. $unwind are used two times to deconstruct the different arrays. $replaceRoot replaces the input document with the specified document (in this case subdocument, files) and final $match filters files arrays that we deconstructed previously, based on your condition. First $match is just for performance reasons, you can delete it if you want.

You can see how stages works in https://mongoplayground.net/p/hoz24xP_BNV

See mongo aggregation framework documentation if you want to learn more about it (https://docs.mongodb.com/manual/aggregation/)

  • Related