$slice (projection)

On this page本页内容

Definition定义

$slice

The $slice projection operator specifies the number of elements in an array to return in the query result.$slice投影运算符指定数组中要在查询结果中返回的元素数。

Disambiguation消除歧义

For information on limiting the size of an array during an update with $push, see the $slice modifier instead.有关使用$push更新期间限制数组大小的信息,请参阅$slice修改器。

For aggregation operator, see $slice aggregation operator instead.有关聚合运算符,请参阅$slice聚合运算符。

Syntax语法

The $slice has one of the following syntax forms:$slice具有以下语法形式之一:

db.collection.find(
   <query>,
{ <arrayField>: { $slice: <number> } });

or或者

db.collection.find(
   <query>,
{ <arrayField>: { $slice: [ <number>, <number> ] } });
ValueDescription描述
$slice: <number>

Specifies the number of elements to return in the <arrayField>. 指定要在<arrayField>中返回的元素数。For <number>:对于<number>

  • Specify a positive number n to return the first n elements.指定正数n以返回前n个元素。
  • Specify a negative number n to return the last n elements.指定负数n以返回最后n个元素。

If the <number> is greater than the number of array elements, the query returns all array elements.如果<number>大于数组元素的数量,则查询将返回所有数组元素。

$slice: [ <number to skip>, <number to return> ]

Specifies the number of elements to return in the <arrayField> after skipping the specified number of elements starting from the first element. 指定从第一个元素开始跳过指定数量的元素后,在<arrayField>中返回的元素数。You must specify both elements.必须同时指定这两个元素。

For the <number to skip>:对于<number to skip>

  • Specify a positive number n to skip n elements from the start of the array; i.e. 0th index position. 指定一个正数n,从数组的开头跳过n个元素;亦即,第0指数位置。Based on a zero-based array index, 1 indicates the starting position of the 2nd element, etc. 根据从零开始的数组索引,1表示第二个元素的起始位置,以此类推。If n is greater than the number of array elements, the query returns an empty array for the <arrayField>.如果n大于数组元素数,则查询将为<arrayField>返回一个空数组。
  • Specify a negative number n to skip backward n elements from the start of the array; i.e. 0th index position Based on a zero-based array index (i.e. the first element is at index 0), -1 indicates the starting position of the last element, etc. 指定一个负数n,从数组开始向后跳过n个元素;亦即,基于零基数组索引的第0个索引位置(即第一个元素位于索引0处),-1表示最后一个元素的起始位置,以此类推。If the absolute value of the negative number is greater than the number of array elements, the starting position is the start of the array.如果负数的绝对值大于数组元素数,则起始位置为数组的起始位置。

For the <number to return>, you must specify a positive number n to return the next n elements, starting after skipping the specified number.对于<number to return>,必须指定一个正数n以返回接下来的n个元素,从跳过指定的数字开始。

Behavior行为

$slice of Embedded Array嵌入式数组的$slice

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.从MongoDB 4.4开始,嵌套文档中数组的$slice投影不再返回嵌套文档中的其他字段,因为该投影是包含投影的一部分。

For example, consider a collection inventory with documents that contain a size field:例如,考虑包含size字段的文档的集合inventory

{ 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:从MongoDB 4.4开始,以下操作仅使用colors数组的指定部分投影_id字段(默认情况下)、qty字段和details字段:

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. 如果$slice投影是排除投影的一部分,则该操作将继续返回嵌套文档中的其他字段。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.投影排除了_id字段和colors数组中位于指定切片之外的元素,并返回所有其他字段。

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.$slice投影本身被认为是一种排除。

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.在以前的版本中,$slice投影还包括嵌套文档中的其他字段,无论该投影是包含还是排除。

View Restriction视图限制

db.collection.find() operations on views do not support $slice projection operator.视图上的db.collection.find()操作不支持$slice投影运算符。

$ Positional Operator and $slice Restriction$位置运算符和$slice限制

Starting in MongoDB 4.4, find and findAndModify projection cannot include $slice projection expression as part of a $ projection expression.从MongoDB 4.4开始,findfindAndModify投影不能将$slice投影表达式作为$投影表达式的一部分。

For example, starting in MongoDB 4.4, the following operation is invalid:例如,从MongoDB 4.4开始,以下操作无效:

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 ($).MongoDB已经有一个限制,顶级字段名不能以美元符号($)开头。

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. 在以前的版本中,MongoDB返回instock数组中与查询条件匹配的第一个元素(instock.$);亦即,位置投影"instock.$"优先,而$slice:1是不可操作的。The "instock.$": { $slice: 1 } does not exclude any other document field."instock.$": { $slice: 1 }不排除任何其他文档字段。

Path Collision: $slice of an Array and Embedded Fields路径冲突:数组的$slice和嵌入字段

Starting in MongoDB 4.4, find and findAndModify projection cannot contain both a $slice of an array and a field embedded in the array.从MongoDB 4.4开始,findfindAndModify投影不能同时包含数组的$slice和数组中嵌入的字段。

For example, consider a collection inventory that contains an array field instock:例如,考虑包含数组字段instock的集合inventory

{ ..., 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:从MongoDB 4.4开始,以下操作失败,出现“路径冲突”错误:

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. 在以前的版本中,投影应用两个投影,并返回instock数组中的第一个元素($slice:1),但不显示投影元素中的warehouse字段。Starting in MongoDB 4.4, to achieve the same result, use the db.collection.aggregate() method with two separate $project stages.从MongoDB 4.4开始,为了获得相同的结果,使用db.collection.aggregate()方法,包含两个单独的$project阶段。

See also参阅

Projection

Examples示例

Create an example collection posts with the following documents:使用以下文档创建一个示例集合post

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返回包含前3个元素的数组

The following operation uses the $slice projection operator on the comments array to return the array with its first three elements. 下面的操作使用comments数组上的$slice投影运算符返回包含前三个元素的数组。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返回包含最后3个元素的数组

The following operation uses the $slice projection operator on the comments array to return the array with its last three elements. 下面的操作使用comments数组上的$slice投影运算符返回带有最后三个元素的数组。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跳过第一个元素后返回一个包含3个元素的数组

The following operation uses the $slice projection operator on the comments array to:以下操作使用comments数组上的$slice投影运算符:

  • 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跳过最后一个元素后返回一个包含3个元素的数组

The following operation uses the $slice projection operator on the comments array to下面的操作使用comments数组上的$slice投影运算符

  • 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" } ]
}