MongoDB 4.4 introduced the $first
aggregation pipeline operator.
This operator returns the first element in an array.
Example
Suppose we have a collection called players with the following documents:
{ "_id" : 1, "player" : "Homer", "scores" : [ 1, 5, 3 ] } { "_id" : 2, "player" : "Marge", "scores" : [ 8, 17, 18 ] } { "_id" : 3, "player" : "Bart", "scores" : [ 15, 11, 8 ] }
We can see that each document has a scores
field that contains an array.
We can use $first
to return the first element of each of those arrays.
Example:
db.players.aggregate([
{
$project: {
"firstScore": {
$first: "$scores"
}
}
}
])
Result:
{ "_id" : 1, "firstScore" : 1 } { "_id" : 2, "firstScore" : 8 } { "_id" : 3, "firstScore" : 15 }
We can see that the first element of the array was returned for each document.
This is the equivalent of using the $arrayElemAt
operator with a value of zero (0
):
db.players.aggregate([
{
$project: {
"firstScore": { $arrayElemAt: [ "$scores", 0 ] }
}
}
])
Empty Arrays
If you provide an empty array, $first
will not return a value.
Suppose we insert the following document into our collection:
{ "_id" : 4, "player" : "Farnsworth", "scores" : [ ] }
Let’s run the code again:
db.players.aggregate([
{
$project: {
"firstScore": {
$first: "$scores"
}
}
}
])
Result:
{ "_id" : 1, "firstScore" : 1 } { "_id" : 2, "firstScore" : 8 } { "_id" : 3, "firstScore" : 15 } { "_id" : 4 }
In this case, document 4 didn’t return any value for the array. In fact, it didn’t even return the field name.
Null and Missing Values
If the operand is null or missing, $first
returns null
.
Suppose we insert the following document:
{ "_id" : 5, "player" : "Meg", "scores" : null }
Let’s run the code again:
db.players.aggregate([
{
$project: {
"firstScore": {
$first: "$scores"
}
}
}
])
Result:
{ "_id" : 1, "firstScore" : 1 } { "_id" : 2, "firstScore" : 8 } { "_id" : 3, "firstScore" : 15 } { "_id" : 4 } { "_id" : 5, "firstScore" : null }
This time it returned the field with a value of null
.
Invalid Operand
The operand for $first
must resolve to an array, null, or missing. Providing an invalid operand results in an error.
To demonstrate this, let’s try to use $first
against the player
field (which isn’t an array):
db.players.aggregate([
{
$project: {
"firstPlayer": {
$first: "$player"
}
}
}
])
Result:
Error: command failed: { "ok" : 0, "errmsg" : "$first's argument must be an array, but is string", "code" : 28689, "codeName" : "Location28689" } : aggregate failed : _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:18:14 _assertCommandWorked@src/mongo/shell/assert.js:618:17 assert.commandWorked@src/mongo/shell/assert.js:708:16 DB.prototype._runAggregate@src/mongo/shell/db.js:266:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1046:12 @(shell):1:1
As expected, it returned an error.