Definition
$sliceThe
$sliceprojection operator specifies the number of elements in an array to return in the query result.
Syntax
The $slice has one of the following syntax forms:
db.collection.find( <query>, { <arrayField>: { $slice: <number> } } );
or
db.collection.find( <query>, { <arrayField>: { $slice: [ <number>, <number> ] } } );
Value | Description |
|---|---|
| Specifies the number of elements to return in the
If the |
| Specifies the number of elements to return in the
For the
For the |
Behavior
$slice of Embedded Array
Starting in MongoDB 4.4, the $slice projection of an
array in an nested document no longer returns the other fields in
the nested document when the projection is part of an inclusion
projection.
For example, consider a collection inventory with documents that
contain a size field:
{ item: "socks", qty: 100, details: { colors: [ "blue", "red" ], sizes: [ "S", "M", "L"] } }
Starting in MongoDB 4.4, the following operation projects the
_id field (by default), the qty field, and the details
field with just the specified slice of the colors array:
db.inventory.find( { }, { qty: 1, "details.colors": { $slice: 1 } } )
That is, the operation returns the following document:
{ "_id" : ObjectId("5ee92a6ec644acb6d13eedb1"), "qty" : 100, "details" : { "colors" : [ "blue" ] } }
If the $slice projection is part of an exclusion
projection, the operation continues to return the other fields in
the nested document. That is, the following projection is an
exclusion projection. The projection excludes the _id field and
the elements in the colors array that fall outside the specified
slice and returns all other fields.
db.inventory.find( { }, { _id: 0, "details.colors": { $slice: 1 } } )
{ "item" : "socks", "qty" : 100, "details" : { "colors" : [ "blue" ], "sizes" : [ "S", "M", "L" ] } }
The $slice projection by itself is considered an exclusion.
In previous versions, the $slice projection also
include the other fields in the nested document regardless of
whether the projection is an inclusion or an exclusion.
View Restriction
db.collection.find() operations on views do not support $slice projection operator.
$ Positional Operator and $slice Restriction
Starting in MongoDB 4.4, find and findAndModify projection
cannot include $slice projection expression as part of a
$ projection expression.
For example, starting in MongoDB 4.4, the following operation is invalid:
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } ) // Invalid starting in 4.4
MongoDB already has a restriction where top-level field names cannot start with the dollar sign
($).
In previous versions, MongoDB returns the first element
(instock.$) in the instock array that matches the query
condition; i.e. the positional projection "instock.$" takes
precedence and the $slice:1 is a no-op. The "instock.$": {
$slice: 1 } does not exclude any other document field.
Path Collision: $slice of an Array and Embedded Fields
Starting in MongoDB 4.4, find and findAndModify projection
cannot contain both a $slice of an array and a field
embedded in the array.
For example, consider a collection inventory that contains an array
field instock:
{ ..., instock: [ { warehouse: "A", qty: 35 }, { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ], ... }
Starting in MongoDB 4.4, the following operation fails with a Path
collision error:
db.inventory.find( {}, { "instock": { $slice: 1 }, "instock.warehouse": 0 } ) // Invalid starting in 4.4
In previous versions, the projection applies both projections and
returns the first element ($slice: 1) in the instock array
but suppresses the warehouse field in the projected element.
Starting in MongoDB 4.4, to achieve the same result, use the
db.collection.aggregate() method with two separate
$project stages.
Tip
Examples
Create an example collection posts with the following documents:
db.posts.insertMany([ { _id: 1, title: "Bagels are not croissants.", comments: [ { comment: "0. true" }, { comment: "1. croissants aren't bagels."} ] }, { _id: 2, title: "Coffee please.", comments: [ { comment: "0. fooey" }, { comment: "1. tea please" }, { comment: "2. iced coffee" }, { comment: "3. cappuccino" }, { comment: "4. whatever" } ] } ])
Return an Array with Its First 3 Elements
The following operation uses the $slice projection
operator on the comments array to return the array with its first
three elements. If the array has less than three elements, all elements
in the array are returned.
db.posts.find( {}, { comments: { $slice: 3 } } )
The operation returns the following documents:
{ "_id" : 1, "title" : "Bagels are not croissants.", "comments" : [ { "comment" : "0. true" }, { "comment" : "1. croissants aren't bagels." } ] } { "_id" : 2, "title" : "Coffee please.", "comments" : [ { "comment" : "0. fooey" }, { "comment" : "1. tea please" }, { "comment" : "2. iced coffee" } ] }
Return an Array with Its Last 3 Elements
The following operation uses the $slice projection
operator on the comments array to return the array with its last
three elements. If the array has less than three elements, all elements
in the array are returned.
db.posts.find( {}, { comments: { $slice: -3 } } )
The operation returns the following documents:
{ "_id" : 1, "title" : "Bagels are not croissants.", "comments" : [ { "comment" : "0. true" }, { "comment" : "1. croissants aren't bagels." } ] } { "_id" : 2, "title" : "Coffee please.", "comments" : [ { "comment" : "2. iced coffee" }, { "comment" : "3. cappuccino" }, { "comment" : "4. whatever" } ] }
Return an Array with 3 Elements After Skipping the First Element
The following operation uses the $slice projection
operator on the comments array to:
Skip the first element such that the second element is the starting point.
Then, return three elements from the starting point.
If the array has less than three elements after the skip, all remaining elements are returned.
db.posts.find( {}, { comments: { $slice: [ 1, 3 ] } } )
The operation returns the following documents:
{ "_id" : 1, "title" : "Bagels are not croissants.", "comments" : [ { "comment" : "1. croissants aren't bagels." } ] } { "_id" : 2, "title" : "Coffee please.", "comments" : [ { "comment" : "1. tea please" }, { "comment" : "2. iced coffee" }, { "comment" : "3. cappuccino" } ] }
Return an Array with 3 Elements After Skipping the Last Element
The following operation uses the $slice projection
operator on the comments array to
Skip backwards from the first element such that the last element is the starting point.
Then, return three elements from the starting point.
If the array has less than three elements after the skip, all remaining elements in the array are returned.
db.posts.find( {}, { comments: { $slice: [ -1, 3 ] } } )
The operation returns the following documents:
{ "_id" : 1, "title" : "Bagels are not croissants.", "comments" : [ { "comment" : "1. croissants aren't bagels." } ] } { "_id" : 2, "title" : "Coffee please.", "comments" : [ { "comment" : "4. whatever" } ] }