Vikas Valechha
Vikas Valechha

Reputation: 323

MongoDB aggregation - how to preform multiple operations in single query?

I am designing a backend for outlet application and i need to write a query to display single outlet images based on image uploaded by the outlet owner. I also need a count of both, images uploaded by the user and images uploaded by the outlet owner. So, how do i achieve this using mongoDB aggregation query. Below is my query:

db.images.aggregate([
      {
        $match: {
          'storeId': storeId,
          'imageType': 1
        }
      },
      {
        $project: {
          '_id': 0,
          'image': 1,
          'imageId': 1,
          'caption': 1,
          'likes': 1,
          'dislikes': 1,
          'uploadTime': 1,
          'imageType': 1
        }
      },
      {
        $match: {
          'storeId': storeId,
          $or: [{ imageType: 1 }, { imageType: 3 }]
        }
      },
      {
        $count: "totalCount"
      } 
    ]

Below are the snapshot of sample documents in the DB:

[
  {
    "imageId": "siyaram_image_1",
    "reviewId": "#review_id",
    "storeId": "#store_id",
    "username": "[email protected]",
    "image": "reviews/siyaram_image_1.jpg",
    "imageType": 1,
    "likes": 0,
    "dislikes": 0,
    "status": 4
  },
  {
    "imageId": "siyaram_image_2",
    "reviewId": "#review_id",
    "storeId": "#store_id",
    "username": "[email protected]",
    "image": "reviews/siyaram_image_2.jpg",
    "imageType": 1,
    "likes": 0,
    "dislikes": 0,
    "status": 4
  },
  {
    "imageId": "siyaram_image_3",
    "reviewId": "#review_id",
    "storeId": "#store_id",
    "username": "[email protected]",
    "image": "reviews/siyaram_image_3.jpg",
    "imageType": 3,
    "likes": 0,
    "dislikes": 0,
    "status": 4
  },
  {
    "imageId": "siyaram_image_4",
    "reviewId": "#review_id",
    "storeId": "#store_id",
    "username": "[email protected]",
    "image": "reviews/siyaram_image_4.jpg",
    "imageType": 3,
    "likes": 0,
    "dislikes": 0,
    "status": 4
  },
  {
    "imageId": "siyaram_image_5",
    "reviewId": "#review_id",
    "storeId": "#store_id",
    "username": "[email protected]",
    "image": "reviews/siyaram_image_5.jpg",
    "imageType": 3,
    "likes": 0,
    "dislikes": 0,
    "status": 4
  }
]

And the expected result:

{
  "total_image_count": 5,
  "images": [
    {
      "imageId": "siyaram_image_1",
      "reviewId": "#review_id",
      "storeId": "#store_id",
      "username": "[email protected]",
      "image": "reviews/siyaram_image_1.jpg",
      "imageType": 1,
      "likes": 0,
      "dislikes": 0,
      "status": 4
    },
    {
      "imageId": "siyaram_image_2",
      "reviewId": "#review_id",
      "storeId": "#store_id",
      "username": "[email protected]",
      "image": "reviews/siyaram_image_2.jpg",
      "imageType": 1,
      "likes": 0,
      "dislikes": 0,
      "status": 4
    }
  ]
}

Upvotes: 1

Views: 317

Answers (1)

Saravana
Saravana

Reputation: 12817

you can use $facet, with $facet you can do multiple operations on same document for different fields

db.images.aggregate(
    [
        {$facet : {
            totalCount : [
                { $match : {"storeId" : "#store_id"} },
                { $count : "storeId" }
            ],
            images : [
                { $match : {"storeId" : "#store_id", "imageType": 1} }
            ]
        }},
        {$addFields : {totalCount : {$arrayElemAt : ["$totalCount.storeId",0]}}}
    ]
)

output

> db.images.aggregate( [ {$facet : { totalCount : [ { $match : {"storeId" : "#store_id"} }, { $count : "storeId" } ], images : [ { $match : {"storeId" : "#store_id", "imageType": 1} } ] }}, {$addFields : {totalCount : {$arrayElemAt : ["$totalCount.storeId",0]}}} ] ).pretty()
{
    "totalCount" : 5,
    "images" : [
        {
            "_id" : ObjectId("5a6c2ac0a52367a6bc65755e"),
            "imageId" : "siyaram_image_1",
            "reviewId" : "#review_id",
            "storeId" : "#store_id",
            "username" : "[email protected]",
            "image" : "reviews/siyaram_image_1.jpg",
            "imageType" : 1,
            "likes" : 0,
            "dislikes" : 0,
            "status" : 4
        },
        {
            "_id" : ObjectId("5a6c2ac0a52367a6bc65755f"),
            "imageId" : "siyaram_image_2",
            "reviewId" : "#review_id",
            "storeId" : "#store_id",
            "username" : "[email protected]",
            "image" : "reviews/siyaram_image_2.jpg",
            "imageType" : 1,
            "likes" : 0,
            "dislikes" : 0,
            "status" : 4
        }
    ]
}
> 

Upvotes: 1

Related Questions