Home > Enterprise >  Get count of documents matching different conditions
Get count of documents matching different conditions

Time:11-24

I have collection: bookSchema as:

[
    {
      _id: ObjectId("637d05dc32428ed75ea08d09"),
      book_details: {
        book_name: "random123",
        book_auth: "Amber"
      }
    },
    {
      _id: ObjectId("637d0673ce0f17f6c473dee2"),
      book_details: {
        book_name: "random321",
        book_auth: "Amber"
      }
    },
    {
      _id: ObjectId("637d069a3d597c8458ebe4ec"),
      book_details: {
        book_name: "random676",
        book_auth: "Amber"
      }
    },
    {
      _id: ObjectId("637d06c05b32d503007bcb54"),
      book_details: {
        book_name: "random999",
        book_auth: "Saurav"
      }
    }
  ]

Desired O/P to show as:

{
  score_ambr: 3,
  score_saurabh: 1
}

For this I tried as:

db.bookSchema.aggregate([
  {
    "$group": {
      "_id": {
        "$eq": [
          "$book_details.book_auth",
          "Amber"
        ]
      },
      "score_ambr": {
        "$sum": 1
      }
    },

  },
  {
    "$group": {
      "_id": {
        "$eq": [
          "$book_details.book_auth",
          "Saurav"
        ]
      },
      "score_saurabh": {
        "$sum": 1
      }
    },

  }
])

I tried using $group to as I want to group all the matching documents in one and use $count to give the number of count for the matching documents but it doesn't seem to be working and gives the O/P as

O/P:

[
  {
    "_id": false,
    "score_sau": 2
  }
]

MongoDB Playground: https://mongoplayground.net/p/cZ64KwAmwlv

CodePudding user response:

I don't know what mean 3 and 1 in your example but if I've understood correctly you can try this query:

The trick here is to use $facet to create "two ways" in the aggregation. One option will filter by Amber and the other one by Saurav.

And then, as values are filtered, you only need yo know the size of the array generated.

db.collection.aggregate([
  {
    "$facet": {
      "score_ambr": [
        {
          "$match": {
            "book_details.book_auth": "Amber"
          }
        }
      ],
      "score_saurabh": [
        {
          "$match": {
            "book_details.book_auth": "Saurav"
          }
        }
      ]
    }
  },
  {
    "$project": {
      "score_ambr": {
        "$size": "$score_ambr"
      },
      "score_saurabh": {
        "$size": "$score_saurabh"
      }
    }
  }
])

Example here

Note that in this way you avoid to use $group.

CodePudding user response:

It looks like what you want is two group twice and create a dynamic key from the book_details.book_auth:

db.bookSchema.aggregate([
  {$group: {_id: "$book_details.book_auth", count: {$sum: 1}}},
  {$group: {
      _id: 0, 
      data: {$push: {
          k: {$concat: ["score_", {$toLower: "$_id"}]},
          v: {$sum: "$count"}
      }}
  }},
  {$replaceRoot: {newRoot: {$arrayToObject: "$data"}}}
])

See how it works on the playground example

  • Related