The aggregation framework is what you are looking for here. You obtain the results mainly from the $cond operator within a $group pipeline:
db.parts.aggregate([
{ "$group": {
"_id": null,
"callbacks": {
"$sum": {
"$cond": [
{ "$ne": [{ "$ifNull": ["$callback",""]}, "" ] },
1,
0
]
}
},
"emptycallbacks": {
"$sum": {
"$cond": [
{ "$eq": [ "$callback", "" ] },
1,
0
]
}
},
"missingcallbacks": {
"$sum": {
"$cond": [
{"$ifNull": [ "$callback", false ] },
0,
1
]
}
}
}}
])
Each is using different comparison operators but mainly $ifNull to test whether the field exists in the document or not. Since $cond is a ternary operator, the second and third arguments are evaluated from where the condition is true or false respectively.
Those values are passed to the $sum operator to add them up. And the null as the grouping key means to add up everything in your collection without "grouping" on a specific field value.
Given the following documents:
{ "callback" : "a" }
{ "callback" : "" }
{ "other" : "a" }
{ "callback" : "" }
{ "something" : "a" }
{ "else": "a" }
The result is:
{ "_id" : null, "callbacks" : 1, "emptycallbacks" : 2, "missingcallbacks" : 3 }
Which shows all conditions are counting correctly.
You will likely need to expand on that logic for your actual documents, but this is the general direction.