0

I am new to MongoDB and I am stuck in the below scenario.

I have a collection that contains duplicate docs. I just want to get the sum of the property in each doc excluding the duplicate docs.

My Docs looks like this:

{"_id":"5dd629461fc50b782479ea90",
"referenceId":"5dd581f10859d2737965d23a",
"sellingId":"319723fb80b1a297cf0803abad9bc60787537f14a6a37d6e47",
"account_name":"mrfsahas1234",
"vendor_name":"testaccount2",
"action_type":"purchase",
"product_name":"Bottle",
"product_quantity":10,
"transactionId":"319723fb80b1a297cf0803abad9bc60787537f14a6a37d6e47",
"uid":"2019-11-20T17:39:17.405Z",
"createdAt":"2019-11-21T08:56:56.589+00:00",
"updatedAt":"2019-11-21T08:56:56.589+00:00","__v":0
},
{
"_id":"5dd629461fc50b782479ea90",
"referenceId":"5dd581f10859d2737965d23a",  
"sellingId":"320a9a2f814a45e01eb98344c9af708fa2864d81587e5914",
 "account_name":"mrfsahas1234",
 "vendor_name":"testaccount2",
 "action_type":"purchase",
 "product_name":"Bottle",
 "product_quantity":50, 
 "transactionId":"320a9a2f814a45e01eb98344c9af708fa2864d81587e5914",
 "uid":"2019-11-20T17:39:17.405Z",
},
{
"_id":"5dd629461fc50b782479ea90",
"referenceId":"5dd581f10859d2737965d23a",  
"sellingId":"320a9a2f814a45e01eb98344c9af708fa2864d81587e5914",
 "account_name":"mrfsahas1234",
 "vendor_name":"testaccount2",
 "action_type":"purchase",
 "product_name":"Bottle",
 "product_quantity":50, 
 "transactionId":"320a9a2f814a45e01eb98344c9af708fa2864d81587e5914",
 "uid":"2019-11-20T17:39:17.405Z",
},

Currently, I am doing this:

MaterialsTrack.aggregate([
            {
                $match: {
                    $and: [
                        {product_name: product_name},
                        {account_name: account_name},
                        {action_type: 'purchase'},
                        {uid:uid}
                    ]
                }
            },
            {
                $group: {_id: "$sellingId", PurchseQuantity: {$sum: "$product_quantity"}}
            },
        ])

It returns the sum of product_quantity all the matching docs (including the duplicate docs). Current Output:

{_id: "320a9a2f814a45e01eb98344c9af708fa2864d81587e5914", PurchseQuantity:110}

Expected Output:

{_id: "320a9a2f814a45e01eb98344c9af708fa2864d81587e5914", PurchseQuantity:60}

I want to get the sum of only unique docs. How can I achieve it? Thanks in advance!

Saumay Paul
  • 405
  • 1
  • 7
  • 21
  • You need distinct values. See this https://stackoverflow.com/questions/16368638/mongodb-distinct-aggregation/35187100#35187100 – Vigen Nov 21 '19 at 07:52

2 Answers2

1

What about adding $addToSet to your aggregations pipeline

MaterialsTrack.aggregate([
            {
                $match: {
                    $and: [
                        {product_name: product_name},
                        {account_name: account_name},
                        {action_type: 'purchase'},
                        {uid:uid}
                    ]
                }
            },
            {
                $group: {_id: "$sellingId", PurchseQuantity: {$sum: "$product_quantity"},"list" : {$addToSet : "$list"}}
            },
        ])
Rebai Ahmed
  • 1,509
  • 1
  • 14
  • 21
1

You need to sum inside of the $group _id field, and then use the replaceRoot to achieve the the result you wanted.

MaterialsTrack.aggregate([
  {
    $match: {
      $and: [
        {
          product_name: "Bottle"
        },
        {
          account_name: "mrfsahas1234"
        },
        {
          action_type: "purchase"
        },
        {
          uid: "2019-11-20T17:39:17.405Z"
        }
      ]
    }
  },
  {
    $group: {
      _id: {
        sellingId: "$sellingId",
        PurchaseQuantity: {
          $sum: "$product_quantity"
        }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        _id: "$_id.sellingId",
        PurchaseQuantity: "$_id.PurchaseQuantity"
      }
    }
  }
]);

Sample Output:

[
  {
    "PurchaseQuantity": 50,
    "_id": "320a9a2f814a45e01eb98344c9af708fa2864d81587e5914"
  }
]

Playground:

https://mongoplayground.net/p/MOneCRiSlO0

SuleymanSah
  • 17,153
  • 5
  • 33
  • 54