Search code examples
mongodbsubtraction

How to make subtract operation using result of projected Field in MongoDb


I have a collection myCollection with array of members and number of places:

{
   name : String,
   members: [{status : Number, memberId : {type: Schema.Types.ObjectId, ref: 'members'}],
   nbPlaces : Number
}

and i have this data

"_id" : ObjectId("5e83791eb49ab07a48e0282b")
   "members" : [ 
        {
            "status" : 1,
            "_id" : ObjectId("5e83791eb49ab07a48e0282c"),
            "memberId" : ObjectId("5e7dbf5b257e6b18a62f2da9")
        }, 
        {
            "status" : 2,
            "_id" : ObjectId("5e837944b49ab07a48e0282d"),
            "memberId" : ObjectId("5e7de2dbe027f43adf678db8")
        }
    ],
  "nbPlaces": 5

I want to make an operation $subtract between projected field and **nbPlaces ** field, like this, but it returns null.

db.getCollection('events').aggregate([
    {$match: {_id: ObjectId("5e83791eb49ab07a48e0282b")}},

         {   $project: {
              nbMembers: {
                    "$size":{
                        $filter: {
                            input: "$members",
                            as: "member",
                            cond: {$eq: ["$$member.status", 1]}
                        }
                    }
                },

                 "nbPlaces": 1,
                 "freePlaces": {$subtract : ["$nbPlaces", "$nbMembers"]}
            }

        }

    ])

How can I do it, thank you

Result

{
    "_id" : ObjectId("5e83791eb49ab07a48e0282b"),
    "nbPlaces" : 5,
    "nbMembers" : 1,
    "freePlaces" : null
}

Solution

  • You should use the nbMembers variable out of the project scope. Because it is not calculated yet in the project scope.

    db.getCollection('events').aggregate([
        {$match: {_id: ObjectId("5e83791eb49ab07a48e0282b")}},
        {$project: {
            nbMembers: {
                "$size":{
                    $filter: {
                        input: "$members",
                        as: "member",
                        cond: {$eq: ["$$member.status", 1]}
                        }
                     }
                  },
                    "nbPlaces": 1
                }
            },
         { $addFields: { "freePlaces": {$subtract : ["$nbPlaces", "$nbMembers"] } } }
     ])
    

    Result:

    {
        "_id" : ObjectId("5e83791eb49ab07a48e0282b"),
        "nbPlaces" : 5.0,
        "nbMembers" : 1,
        "freePlaces" : 4.0
    }