If you have the latest MongoDB 3.4 then you can do this in an aggregation statement with $objectToArray
:
Model.aggregate([
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$cond": {
"if": { "$eq": [
{ "$size": {
"$objectToArray": { "$ifNull": [ "$preferences", { } ] }
}},
20
]},
"then": 1,
"else": 0
}
}
}
}}
])
The new operator $objectToArray
will take an object of "key/value" pairs and turn this into an array. So this:
{ "a": 1, "b": 2 }
Becomes this:
[ { "k": "a", "v": 1 }, { "k": "b", "v": 2 } ]
As an array, you can use operators like $size
to count the number of "keys", which is now equal to the entries in the array.
For earlier versions you can use a $where
condition in JavaScript evaluation:
Model.find(function() {
return (this.hasOwnProperty("preferences")) ?
Object.keys(this.preferences).length == 20 : false;
}).count()
The latter not really being an "aggregation", but the cursor count is really all you can get from a JavaScript evaluation.