In MongoDB, the $size
aggregation pipeline operator counts and returns the total number of items in an array.
The $size
operator accepts one argument. The argument can be any valid expression that resolves to an array.
Example
Suppose we have a collection called test
with the following documents:
{ "_id" : 1, "data" : [ ] } { "_id" : 2, "data" : [ "a" ] } { "_id" : 3, "data" : [ "a", "b" ] } { "_id" : 4, "data" : [ "a", "b", "c" ] } { "_id" : 5, "data" : [ 1, 1, 1, 1 ] }
We can use $size
to return the number of items in the arrays in the respective data
fields.
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $size: [ "$data" ] }
}
}
]
)
Result:
{ "data" : [ ], "result" : 0 } { "data" : [ "a" ], "result" : 1 } { "data" : [ "a", "b" ], "result" : 2 } { "data" : [ "a", "b", "c" ], "result" : 3 } { "data" : [ 1, 1, 1, 1 ], "result" : 4 }
Nested Arrays
The $size
operator does not descend into nested arrays and count their elements. It evaluates the array from the top level.
Suppose we have the following document in our collection:
{ "data" : [ [ 1, 2 ], 3 ], "result" : 2 }
And we apply $size
to that:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $size: [ "$data" ] }
}
}
]
)
Result:
{ "data" : [ [ 1, 2 ], 3 ], "result" : 2 }
The nested array is counted as one element (regardless of how many elements it contains).
Wrong Data Types
The argument can be any valid expression, as long as it resolves to an array. If it doesn’t resolve to an array, an error is produced.
Suppose we have the following document:
{ "_id" : 7, "data" : 3 }
The data
field does not resolve to an array.
Here’s what happens when we apply $size
to that field:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $size: [ "$data" ] }
}
}
]
)
Result:
Error: command failed: { "ok" : 0, "errmsg" : "The argument to $size must be an array, but was of type: double", "code" : 17124, "codeName" : "Location17124" } : aggregate failed : _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:18:14 _assertCommandWorked@src/mongo/shell/assert.js:639:17 assert.commandWorked@src/mongo/shell/assert.js:729:16 DB.prototype._runAggregate@src/mongo/shell/db.js:266:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1058:12 @(shell):1:1
The error message tells us that The argument to $size must be an array, but was of type: double
.
Missing Fields
If the field doesn’t exist in the document, an error is returned.
Suppose we have the following document:
{ "_id" : 8 }
And we apply $size
to that document:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 8 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $size: [ "$data" ] }
}
}
]
)
Result:
Error: command failed: { "ok" : 0, "errmsg" : "The argument to $size must be an array, but was of type: missing", "code" : 17124, "codeName" : "Location17124" } : aggregate failed : _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:18:14 _assertCommandWorked@src/mongo/shell/assert.js:639:17 assert.commandWorked@src/mongo/shell/assert.js:729:16 DB.prototype._runAggregate@src/mongo/shell/db.js:266:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1058:12 @(shell):1:1