Home > Enterprise >  mongo aggregate - group - show number fo childrens
mongo aggregate - group - show number fo childrens

Time:10-04

This is how my documents looks like:

[
  {
    "_id": {
      "$oid": "633a982186c443b693dc240c"
    },
    "date": "2022-09-27",
    "file": "file_1",
    "package": 1,
    "packagecode": "xy/1",
    "pshIdList": [],
    "userList": [
      {
        "userName": "user_1",
        "crDate": "2022.09.28",
        "boolId": 1
      }
    ]
  },
  {
    "_id": {
      "$oid": "633a982186c443b693dc240d"
    },
    "date": "2022-09-27",
    "file": "file_2",
    "package": 2,
    "packagecode": "xy/2",
    "pshIdList": [],
    "userList": []
  }
]

Because of the appearance of the frontend (i have to display a tree structure) i need to group by the documents this way:

db.collection.aggregate([
  {
    $set: {
      "username": {
        $filter: {
          input: "$userList",
          as: "user",
          cond: {
            "$eq": [
              "$$user.boolId",
              1
            ]
          }
        }
      }
    }
  },
  {
    $set: {
      "username": {
        $arrayElemAt: [
          "$username",
          0
        ]
      }
    }
  },
  {
    $set: {
      "username": {
        $ifNull: [
          "$username.userName",
          "na"
        ]
      }
    }
  },
  {
    $group: {
      _id: {
        "date": {
          $concat: [
            "date: ",
            "$date",
            
          ]
        },
        "file": {
          $concat: [
            "file: ",
            "$file"
          ]
        },
        
      },
      "items": {
        $push: {
          "items": {
            $concat: [
              "$packagecode",
              " - ",
              "$username"
            ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id.date",
      "items": {
        $push: {
          "file": "$_id.file",
          "items": "$items"
        }
      }
    }
  }
])

This is the result of the aggregate:

[
  {
    "_id": "date: 2022-09-27",
    "items": [
      {
        "file": "file: file_1",
        "items": [
          {
            "items": "xy/1 - user_1"
          }
        ]
      },
      {
        "file": "file: file_2",
        "items": [
          {
            "items": "xy/2 - na"
          }
        ]
      }
    ]
  }
]

Also need to display the number of childrens of each level, so the output should look like this:

[
  {
    "_id": "date: 2022-09-27 - 2",
    "items": [
      {
        "file": "file: file_1 - 1",
        "items": [
          {
            "items": "xy/1 - user_1"
          }
        ]
      },
      {
        "file": "file: file_2 - 1",
        "items": [
          {
            "items": "xy/2 - na"
          }
        ]
      }
    ]
  }
]

I have no clue how to solve it. I was trying with $set operator, but cannot use group inside that. This is an example playground

CodePudding user response:

You can use $map, to loop over the items array and append the number of children in file, like this:

db.collection.aggregate([
  {
    $set: {
      "username": {
        $filter: {
          input: "$userList",
          as: "user",
          cond: {
            "$eq": [
              "$$user.boolId",
              1
            ]
          }
        }
      }
    }
  },
  {
    $set: {
      "username": {
        $arrayElemAt: [
          "$username",
          0
        ]
      }
    }
  },
  {
    $set: {
      "username": {
        $ifNull: [
          "$username.userName",
          "na"
        ]
      }
    }
  },
  {
    $group: {
      _id: {
        "date": {
          $concat: [
            "date: ",
            "$date",
            
          ]
        },
        "file": {
          $concat: [
            "file: ",
            "$file"
          ]
        },
        
      },
      "items": {
        $push: {
          "items": {
            $concat: [
              "$packagecode",
              " - ",
              "$username"
            ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id.date",
      "items": {
        $push: {
          "file": "$_id.file",
          "items": "$items"
        }
      }
    }
  },
  {
    "$set": {
      "items": {
        "$map": {
          "input": "$items",
          "as": "element",
          "in": {
            items: "$$element.items",
            file: {
              "$concat": [
                "$$element.file",
                " - ",
                {
                  "$toString": {
                    "$size": "$$element.items"
                  }
                }
              ]
            }
          }
        }
      },
      _id: {
        "$concat": [
          "$_id",
          " - ",
          {
            "$toString": {
              "$sum": {
                "$map": {
                  "input": "$items",
                  "as": "element",
                  "in": {
                    "$size": "$$element.items"
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
])

Playground link.

  • Related