简体   繁体   中英

MongoDB nested array aggregation

I want to aggregate data for the following sample array.

 [
  {
    "_id": "5b7c0540342100091a375793",
    "pages": [
      {
        "name": "ABCD",
        "sections": [
          {
            "name": "sectionThird",
            "id": 2,
            "value": [
              10,
              50,
              20
            ]
          }
        ]
      }
    ]
  },
  {
    "_id": "5b3cd546342100514b4683a2",
    "pages": [
      {
        "name": "ABCD",
        "sections": [
          {
            "name": "sectionFourth",
            "id": 2,
            "value": [
              19,
              5,
              8
            ]
          },
          {
            "name": "sectionThird",
            "id": 2,
            "value": [
              60
            ]
          }
        ]
      },
      {
        "name": "EFGH",
        "sections": [
          {
            "name": "sectionFourth",
            "id": 2,
            "value": [
              5
            ]
          },
          {
            "name": "sectionThsads",
            "id": 2,
            "value": [
              8
            ]
          }
        ]
      }
    ]
  }
]

I want the following output:

 [
  {
    "page": "ABCD",
    "sections": [
      {
        "name": "sectionThird",
        "totalValue": 140
      },
      {
        "name": "sectionFourth",
        "totalValue": 32
      }
    ]
  },
  {
    "page": "EFGH",
    "sections": [
      {
        "name": "sectionFourth",
        "totalValue": 5
      },
      {
        "name": "sectionThsads",
        "totalValue": 8
      }
    ]
  }
]

In the above sample array, you can see there are multiple documents with "page" as one of the keys which are also an array of objects. Each page object has a key "name" which is going to be unique for each object in "page" array. The "page" object has "sections" key and they also have "name" key in them which is going to be unique for each object.

So the output array is grouped by page.name then in that its grouped by sections.name from all the page objects with the sum of all the value array throughout sections inside a page object with the same section name.

You can use below aggregation.

$unwind each page and section followed by $group with $sum to sum the values for each section and $push to push the sections values back into page array.

db.col.aggregate([
{"$unwind":"$pages"},
{"$unwind":"$pages.sections"},
{"$group":{
  "_id":{"pagename":"$pages.name","sectionname":"$pages.sections.name"},
  "totalTime":{"$sum":{"$sum":"$pages.sections.value"}}
}},
{"$group":{
  "_id":"$_id.pagename",
  "sections":{"$push":{"name":"$_id.sectionname","totalTime":"$totalTime"}}
}}])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM