In MongoDB, the $allElementsTrue
aggregation pipeline operator evaluates an array as a set and returns true
if no element in the array is false
.
If the array contains an element that is false
, then $allElementsTrue
returns false
.
An array’s element is true
if it’s not false
, null
, 0
, or undefined
.
Example
Suppose we have a collection with the following document:
{ "_id" : 1, "data" : [ 1, 2, 3 ] }
This document contains an array.
We can run the following query with $allElementsTrue
to find out whether or not the array contains an element that is false
:
db.test.aggregate(
[
{ $project: {
_id: 0,
allElementsTrue: { $allElementsTrue: [ "$data" ] } }
}
]
)
Result:
{ "allElementsTrue" : true }
In this case, none of the array elements are false
, and so we get a result of true
.
When the Array Contains False
Let’s add the following document to the collection:
{ "_id" : 2, "data" : [ true, false ] }
And let’s run $allElementsTrue
against that document:
db.test.aggregate(
[
{ $match: { _id: 2 } },
{ $project: {
_id: 0,
allElementsTrue: { $allElementsTrue: [ "$data" ] } }
}
]
)
Result:
{ "allElementsTrue" : false }
This time we get false
, even though there’s another element that is true
. This is to be expected, because $allElementsTrue
returns false
whenever there is at least one element that is false
, regardless of how many other elements are true.
Empty Arrays
Empty arrays return true
.
Suppose we add the following document to our collection:
{ "_id" : 3, "data" : [ ] }
This document contains an empty array.
Now let’s run $allElementsTrue
again:
db.test.aggregate(
[
{ $match: { _id: 3 } },
{ $project: {
_id: 0,
allElementsTrue: { $allElementsTrue: [ "$data" ] } }
}
]
)
Result:
{ "allElementsTrue" : true }
As expected, it returns true
.
Null, 0, and Undefined Values
It’s not entirely true that $allElementsTrue
evaluates to false
only when the array contains false
.
The $allElementsTrue
operator also evaluates to false
whenever an array contains null
, 0
, or undefined
values.
Suppose we add the following documents to our collection:
{ "_id" : 4, "data" : [ 1, null, 3 ] } { "_id" : 5, "data" : [ 1, undefined, 3 ] } { "_id" : 6, "data" : [ 0, 1, 2 ] }
Each document’s array contains an element of either null
, 0
, or undefined
.
Now let’s run $allElementsTrue
against those documents:
db.test.aggregate(
[
{ $match: {_id: { $in: [4,5,6] }} },
{ $project: {
allElementsTrue: { $allElementsTrue: [ "$data" ] } }
}
]
)
Result:
{ "_id" : 4, "allElementsTrue" : false } { "_id" : 5, "allElementsTrue" : false } { "_id" : 6, "allElementsTrue" : false }
All documents return false
as expected.
Nested Arrays
If the array contains a nested array that contains an element that is false
, then that is not enough for $allElementsTrue
to return false
. As far as $allElementsTrue
is concerned, the nested array is the element, and therefore not false
.
To demonstrate what I mean, suppose we insert the following documents:
{ "_id" : 7, "data" : [ 1, [ false ], 3 ] } { "_id" : 8, "data" : [ 1, [ false ], false ] }
Now let’s run $allElementsTrue
against those two documents:
db.test.aggregate(
[
{ $match: {_id: { $in: [7,8] }} },
{ $project: {
allElementsTrue: { $allElementsTrue: [ "$data" ] } }
}
]
)
Result:
{ "_id" : 7, "allElementsTrue" : true } { "_id" : 8, "allElementsTrue" : false }
We can see that the first document returned true
and the second returned false
.
This is because, in the first document, the false
value is nested inside another array, and therefore doesn’t count as a false
value (i.e. the array itself is the value).
The second document however, also contains false as one of the array elements, and therefore, that value is what causes $allElementsTrue
to evaluate to false
.