Docs 菜单
Docs 主页
/
MongoDB Manual
/ / / /

$slice(投影)

在此页面上

  • 定义
  • 语法
  • 行为
  • 示例
$slice

$slice 投影操作符指定了要在查询结果中返回的数组中的元素数。

注意

消歧

有关在更新期间使用 $push限制大量大小的信息,请改为参阅$slice修饰符。

有关聚合操作符,请参阅 $slice 聚合操作符。

$slice 采用以下语法形式之一:

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

or

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

$slice: <number>

指定了要在 <arrayField> 中返回的元素数。对于 <number>

  • 指定正数 n 以返回前 n 个元素。

  • 指定一个负数 n 以返回最后的 n 个元素。

如果 <number> 大于数组元素数,此查询则会返回所有数组元素。

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

指定从第一个元素开始跳过指定数量的元素后要在 <arrayField> 中返回的元素数量。必须同时指定这两个元素。

对于 <number to skip>

  • 指定一个正数 n 以从数组开头跳过 n 个元素;即第 0 个索引位置。基于从零开始的数组索引,1 表示第二个元素的起始位置,依此类推。如果 n 大于数组元素的数量,则查询将为 <arrayField> 返回一个空数组。

  • 指定一个负数 n 可从数组开头向后跳过 n 个元素;即,第 0 个索引位置。针对从零开始的数组索引(即,第一个元素位于索引 0),-1 表示最后一个元素的起始位置。如果此负数的绝对值大于数组元素数,则起始位置为数组的起始位置。

对于 <number to return>,您必须指定一个正数 n,以返回在跳过指定数字之后的接下来 n 个元素。

当投影属于包含投影的一部分时,嵌套文档中数组的 $slice 投影不再返回嵌套文档中的其他字段。

例如,考虑一个文档集合 inventory,其中的文档包含 size 字段:

{ item: "socks", qty: 100, details: { colors: [ "blue", "red" ], sizes: [ "S", "M", "L"] } }

以下操作仅使用 colors 数组的指定切片来投影 _id 字段(默认)、qty 字段和 details 字段:

db.inventory.find( { }, { qty: 1, "details.colors": { $slice: 1 } } )

换言之,该操作会返回以下文档:

{ "_id" : ObjectId("5ee92a6ec644acb6d13eedb1"), "qty" : 100, "details" : { "colors" : [ "blue" ] } }

如果 $slice 投影是排除投影的一部分,则该操作将继续返回嵌套文档中的其他字段。也就是说,以下投影是排除投影。投影会排除 _id 字段以及 colors 数组中位于指定切片之外的元素,并返回所有其他字段。

db.inventory.find( { }, { _id: 0, "details.colors": { $slice: 1 } } )
{ "item" : "socks", "qty" : 100, "details" : { "colors" : [ "blue" ], "sizes" : [ "S", "M", "L" ] } }

$slice 投影自身被认为一种排除操作。

在以前的版本中,$slice 投影还包括嵌套文档中的其他字段,而无论该投影是包含性投影还是排除性投影。

针对视图db.collection.find() 操作不支持 $slice 投影运算符。

findfindAndModify 投影不能包含 $slice 投影表达式作为 $ 投影表达式的一部分。

例如,以下操作无效:

db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } )

在之前的版本中,MongoDB 返回instock数组中符合查询条件的第一个元素( instock.$);即位置投影"instock.$"优先,而$slice:1是无需操作。"instock.$": { $slice: 1 }不排除任何其他文档字段。

findfindAndModify 投影不能同时包含数组的 $slice 和嵌入数组的字段。

例如,考虑包含数组字段 instock 的集合 inventory

{ ..., instock: [ { warehouse: "A", qty: 35 }, { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ], ... }

以下操作失败并显示 Path collision 错误:

db.inventory.find( {}, { "instock": { $slice: 1 }, "instock.warehouse": 0 } )

在以前的版本中,投影应用两个投影并返回instock数组中的第一个元素 ($slice: 1),但抑制投影元素中的warehouse字段。从 MongoDB 4.4 开始,要获得相同的结果,请使用具有两个独立 $project 阶段的 db.collection.aggregate() 方法。

提示

另请参阅:

创建一个包含以下文档的集合 posts

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

以下操作使用 comments 数组上的 $slice 投影运算符来返回数组及其前三个元素。如果数组的元素少于三个,则返回数组中的所有元素。

db.posts.find( {}, { comments: { $slice: 3 } } )

该操作将返回以下文档:

{
"_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" } ]
}

以下操作使用 comments 数组上的 $slice 投影操作符来返回数组及其最后三个元素。如果数组的元素少于三个,则返回数组中的所有元素。

db.posts.find( {}, { comments: { $slice: -3 } } )

该操作将返回以下文档:

{
"_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" } ]
}

以下操作使用 comments 数组上的 $slice 投影操作符:

  • 跳过第一个元素,从而使第二个元素成为起点。

  • 然后,从起点开始返回三个元素。

如果跳转后数组中的元素少于三个,则会返回所有剩余元素。

db.posts.find( {}, { comments: { $slice: [ 1, 3 ] } } )

该操作将返回以下文档:

{
"_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" } ]
}

以下操作使用 comments 数组上的 $slice 投影操作符来

  • 从第一个元素向后跳转,从而以最后一个元素为起点。

  • 然后,从起点开始返回三个元素。

如果跳转后数组中的元素少于三个,则会返回所有剩余元素。

db.posts.find( {}, { comments: { $slice: [ -1, 3 ] } } )

该操作将返回以下文档:

{
"_id" : 1,
"title" : "Bagels are not croissants.",
"comments" : [ { "comment" : "1. croissants aren't bagels." } ]
}
{
"_id" : 2,
"title" : "Coffee please.",
"comments" : [ { "comment" : "4. whatever" } ]
}

后退

$elemMatch