MongoDB, Multiple counters (with $ exists)

I have these 3 queries:

db.mycollection.count({requestA:{$exists:true}}) db.mycollection.count({requestB:{$exists:true}}) db.mycollection.count({requestC:{$exists:true}}) 

I want to make only one request ... So I tried the following:

 db.mycollection.aggregate( [ { $group: { '_id' : { user_id: '$user_id'}, requestA_count: { $sum: { $cond: [ {requestA:{'$exists':true}}, 1, 0 ] } }, requestB_count: { $sum: { $cond: [ {requestB:{'$exists':true}}, 1, 0 ] } }, requestC_count: { $sum: { $cond: [ {requestC:{'$exists':true}}, 1, 0 ] } }, } }, { $project: { _id: 0, user_id: '$_id.user_id', requestA_count: 1, requestB_count: 1, requestC_count: 1 } } ] ); 

But I got an error:

 "errmsg" : "exception: invalid operator '$exists'", 

I assume that we cannot use $ exists with $ project.

Any tips on a good approach? Thanks you

+7
mongodb mongodb-query aggregation-framework
source share
1 answer

You had the right basic idea, but $exists is a query condition, so only w $match valid. You want the $ifNull operator $ifNull to do the same:

 db.mycollection.aggregate( [ { "$group": { "_id" : { "user_id": "$user_id" }, "requestA_count": { "$sum": { "$cond": [ { "$ifNull": ["$requestA", false] }, 1, 0 ] } }, "requestB_count": { "$sum": { "$cond": [ { "$ifNull": ["$requestB", false] }, 1, 0 ] } }, "requestC_count": { "$sum": { "$cond": [ { "$ifNull": ["$requestC", false] }, 1, 0 ] } }, } }, { "$project": { "_id": 0, "user_id": "$_id.user_id", "requestA_count": 1, "requestB_count": 1, "requestC_count": 1 } } ] ); 

So, $ifNull returns the current value of the field, if it exists, or returns the argument "right side" if It is not. A return value other than false is intrepreted as true (unless, of course, the value is actually false).

Essentially, this gives you the same functionality that is logically checked for a property in a document.

+11
source share

All Articles