Search code examples
mongodbnosqlaggregation-frameworkaggregation

MongoDB - aggregation - array of array data selection


I'm want to create an aggregation for the following contents of a collection:

{ "_id": ObjectId("574ffe9bda461e4b4b0043ab"), 
  "list1":  [
     "_id": "54",
     "list2": [
        {
          "lang": "EN",
          "value": "val1"
        },
        {
          "lang": "ES",
          "value": "val2"
        },
        {
          "lang": "FR",
          "value": "val3"
        },
        {
          "lang": "IT",
          "value": "val3"
        }
     ] 
  ]
}

From this collection i want to get as Object ("id": "54", "value": "val3") the returned Object is based on condition : list1.id = "54" and list2.lang = "IT"


Solution

  • You can try a simple combination of $match and $unwind to traverse your nested arrays:

    db.collection.aggregate([
        {
            $unwind: "$list1"
        },
        {
            $match: { "list1._id": "54" }
        },
        {
            $unwind: "$list1.list2"
        },
        {
            $match: { "list1.list2.lang": "IT" }
        },
        {
            $project: {
                _id: "$list1._id",
                val: "$list1.list2.value"
            }
        }
    ])
    

    Mongo Playground.

    If the list._id field is unique you can index it and swap first first two pipeline stages to filter out other documents before running $unwind:

    db.collection.aggregate([
        {
            $match: { "list1._id": "54" }
        },
        {
            $unwind: "$list1"
        },        
        {
            $unwind: "$list1.list2"
        },
        {
            $match: { "list1.list2.lang": "IT" }
        },
        {
            $project: {
                _id: "$list1._id",
                val: "$list1.list2.value"
            }
        }
    ])