I am running an aggregate function below. A document may or may not have an element, and I just want to return true/false. The element is huge if it does exist, so returning the entire element creates many problems and is not needed.
To preface the problem, I am in a production environment on version 3.0.4 and upgrading to 3.4 is not an option at this time, although it looks like that version has better solutions.
To test this, I have a document in a collection mycollection. The document has an element exists which is an object containing other elements. It does not have an element called notexists
db.runCommand({
"aggregate": "mycollection",
"pipeline": [{
"$match": {...}
}, {
"$sort": {...}
}, {
"$group": {...}
}, {
"$limit": 10
}, {
"$project": {
"aggregated": {
"$map": {
"input": "$mycollection",
"as": "document",
"in": {
"exists_test":{"$eq":["$$document.exists",null]},
"not_exists_test":{"$eq":["$$document.notexists",null]},
"exists_test_ifnull":{"$ifNull":["$$document.exists","test"]},
"not_exists_test_ifnull":{"$ifNull":["$$document.notexists","test"]},
"exists_content": "$$document.exists"
...
}
}
},
"success": {
"$cond": {
"if": { "$gt": ["$status", 0] },
"then": "false",
"else": "true"
}
}
}
}]
})
Unfortunately, this returns a document:
{
aggregated: [{
"exists_test": false, (correct)
"not_exists_test": false, (wrong)
"exists_test_ifnull": content from document.exists, (correct)
"not_exists_test_ifnull": "test", (correct)
"exists_content": content from document.exists, (correct)
}]
}
It seems that "not_exists_test":{"$eq":["$$document.notexists",null]}, should return true, since $ifNull does accurately reflect that the value is null.
Try "not_exists_test": { "$gt": ["$$document.notexists", null] }, as implied in the BSON types comparison order .
For Mongodb 3.2, it works with single $ sign,
"not_exists_test": { "$gt": ["$document.notexists", null] }