Sha
Sha

Reputation: 1181

MongoDB merge queries as aggregated pipeline

I have a two separated queries.

  1. First one is to find removed items.

  2. Second one is to check whether all items are removed on same country by itemId.

Can I merge it as pipeline?

Example Input:

itemId      removed     country
1           true        US
1           false       TR
2           true        US
2           true        RU

Example Output:

itemId: 2

Expected: (itemId: 2) Find itemIds that removed from all countries by itemId.

My code looks like:

db.collection.find({removed: true}, {itemId: 1}) -> Extract itemIdList

forEach id: itemIdList: [1, 2]
  if db.collection.find({removed: false, itemId: id}).count() > 0
     remove itemId from itemIdList
return remainingItems: [2];

Upvotes: 0

Views: 42

Answers (1)

Umer Abbas
Umer Abbas

Reputation: 1876

Hi you can achieve this by aggregate first group items by item id and counting total removed true, and total items. now in $match stage if the total number of items equals the removed true count that means, this itemId has removed true for all countries, and simply push the itemIds into an array. Working solution

db.collection.aggregate([
    {
        "$group": {
            "_id": "$itemId",
            "itemsArrCount": {
                "$sum": 1
            },
            "totalRemovedTrue": {
                "$sum": {
                    "$cond": [
                        { "$eq": ["$removed", true] },
                        1,
                        0
                    ]
                }
            },        
        }
    },
    {
        "$match": {
            "$expr": {
                "$eq": [ "$itemsArrCount", "$totalRemovedTrue"]
            }
        }
    },
    {
        "$group": {
            "_id": null,
            "itemIds": {
                "$push": "$_id"
            }
        }
    }
])

Upvotes: 1

Related Questions