2

I have the following mongo data structure:

[
  {
    _id: "......",
    libraryName: "a1",
    stages: [
      {
        _id: '....',
        type: 'b1',
      },
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b3',
      },
      {
        _id: '....',
        type: 'b1',
      },
    ],
  },
  {
    _id: "......",
    libraryName: "a1",
    stages: [
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b1',
      },
    ],
  },
    {
    _id: "......",
    libraryName: "a2",
    stages: [
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b2',
      },
      {
        _id: '....',
        type: 'b1',
      },
    ],
  },
]

Assume this is the Session collection. Now, each session document has some irrelevant _id and libraryName key. Furthermore, each document has array of stages documents. Each stage document has some irrelevant _id and type. I want to count 2 things.

First - I want to count for each libraryName, how many session objects it has. The solution for this query would be:

const services = await Session.aggregate(
    [
        {
            $group: {
                _id: "$libraryName",
                count: { $sum: 1 },
            },
        }
    ]
);

Second - I want, per libaryName to count for each stage type how many nested stages documents it has.

So the final result I wish to retrieve is:

[
{
    libraryName: 'a1',
    count: 456,
    stages: [
      {
        type: 'b1',
        count: 43,
      },
      {
        type: 'b2',
        count: 44,
      }
    ],
  },
  {
    libraryName: 'a2',
    count: 4546,
    stages: [
      {
        type: 'b1',
        count: 43
      },
      {
        type: 'b3',
        count: 44
      }
    ]
  }
]

Changed to:

 [
  {
    "_id": "a1",
    "count": 2,
    "stages": [
      {
        "count": 1,
        "type": "b3"
      },
      {
        "count": 3,
        "type": "b1"
      },
      {
        "count": 4,
        "type": "b2"
      }
    ]
  },
  {
    "_id": "a2",
    "count": 1,
    "stages": [
      {
        "count": 1,
        "type": "b1"
      },
      {
        "count": 3,
        "type": "b2"
      }
    ]
  }
]
3
  • How did you arrive at the count: 1 for the (libraryName) "_id": "a2" - in the Second? Commented Jul 20, 2021 at 14:07
  • I have edited/included the expected results version 1 (also) in the question post for clarity). Commented Jul 20, 2021 at 14:35
  • Also please see this: stackoverflow.com/help/how-to-ask Commented Jul 20, 2021 at 14:50

1 Answer 1

1

Using the sample data in the question post and the aggregation query:

db.collection.aggregate([
{ 
    $unwind: "$stages" 
},
{ 
    $group: {
        _id: { libraryName: "$libraryName", type: "$stages.type" }, 
        type_count: { "$sum": 1 } 
    } 
},
{ 
    $group: { 
        _id: { libraryName: "$_id.libraryName" }, 
        count: { "$sum": "$type_count" }, 
        stages: { $push: { type: "$_id.type", count: "$type_count" } }
    } 
},
{ 
    $project: { 
        libraryName: "$_id.libraryName", 
        count: 1, 
        stages: 1, 
        _id: 0  
    } 
}
])

I get the following results:

{
        "libraryName" : "a2",
        "count" : 4,
        "stages" : [
                {
                        "type" : "b1",
                        "count" : 1
                },
                {
                        "type" : "b2",
                        "count" : 3
                }
        ]
}
{
        "libraryName" : "a1",
        "count" : 8,
        "stages" : [
                {
                        "type" : "b3",
                        "count" : 1
                },
                {
                        "type" : "b1",
                        "count" : 3
                },
                {
                        "type" : "b2",
                        "count" : 4
                }
        ]
}


[ EDIT - ADD ] : This is an answer after the question post's expected result is modified. This query uses the question post's sample documents as input.

db.collection.aggregate([
{ 
    $group: { 
        _id: { libraryName: "$libraryName" }, 
        count: { "$sum": 1 },
        stages: { $push: "$stages" }
    } 
},
{ 
    $unwind: "$stages" 
},
{ 
    $unwind: "$stages" 
},
{ 
    $group: {
        _id: { libraryName: "$_id.libraryName", type: "$stages.type" }, 
        type_count: { "$sum": 1 },
        count: { $first: "$count" }
    } 
},
{ 
    $group: { 
        _id: "$_id.libraryName", 
        count: { $first: "$count" },
        stages: { $push: { type: "$_id.type", count: "$type_count" } }
    } 
},
])

The result:

{
        "_id" : "a2",
        "count" : 1,
        "stages" : [
                {
                        "type" : "b2",
                        "count" : 3
                },
                {
                        "type" : "b1",
                        "count" : 1
                }
        ]
}
{
        "_id" : "a1",
        "count" : 2,
        "stages" : [
                {
                        "type" : "b2",
                        "count" : 4
                },
                {
                        "type" : "b3",
                        "count" : 1
                },
                {
                        "type" : "b1",
                        "count" : 3
                }
        ]
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.