翻译原文:https://docs.mongodb.com/manual/reference/operator/update/slice/#examples
$slice(切分)
当进行$push
(插入)操作时,可以通过 $slice
修饰词来限制插入的数组元素个数。如果想从一个只读操作中映射或是返回数组元素中特定的值,详见$slice
映射操作。$slice
修饰词必须搭配$each
修饰词才能使用。不过,你也可以传递一个空数组给$each
修饰词,从而只让$slice
修饰词起作用。1
2
3
4
5
6
7
8{
$push: {
<field>: {
$each: [ <value1>, <value2>, ... ],
$slice: <num>
}
}
}
< num > 的值可以是:
Value | Description |
---|---|
0 | 更新数组<field>为空数组 |
负数 | 更新数组<field>只包含最后<num>个元素 |
正数 | 更新数组<field>只包含开头<num>个元素,适用于2.6以上版本 |
Behavior(行为)
这些修饰词出现的顺序是无关紧要的。不过在上一个版本中,要求$each
修饰词得作为第一个修饰词出现,如果要和$slice
修饰词连用的话。这里有一份关于和$push
搭配使用的修饰词列表,详见Modifiers。
不结合$each
修饰词而只使用$slice
修饰词将会导致出错,不信可以试试。
栗子
从数组末尾切片
一个学生集合包含以下文档:1
{ "_id" : 1, "scores" : [ 40, 50, 60 ] }
下面的操作增加一个新元素到scores数组中,然后使用$slice
将数组修剪为最后五个元素。
1 | db.students.update( |
操作的结果就是将更新后的scores数组切分为最后5个元素1
{ "_id" : 1, "scores" : [ 50, 60, 80, 78, 86 ] }
从数组头部切片
一个学生集合包含以下文档:1
{ "_id" : 2, "scores" : [ 89, 90 ] }
下面的操作增加一个新元素到scores数组中,然后使用$slice
修饰词修剪为前三个元素。1
2
3
4
5
6
7
8
9
10
11db.students.update(
{ _id: 2 },
{
$push: {
scores: {
$each: [ 100, 20 ],
$slice: 3
}
}
}
)
操作的结果就是将更新后的scores数组切分为前三个元素中。
只用slice来更新数组
一个学生集合包含以下文档:1
{ "_id" : 3, "scores" : [ 89, 70, 100, 20 ] }
为了只用$slice
修饰词来更新scores字段,我们得给出要切分的元素数量(比如 -3)赋给slice
修饰词,而且赋一个空数组给$each
修饰词,就像下面的代码:1
2
3
4
5
6
7
8
9
10
11db.students.update(
{ _id: 3 },
{
$push: {
scores: {
$each: [ ],
$slice: -3
}
}
}
)
操作的结果就是将scores数组切分为最后三个元素。
slice
和push
搭配使用
一个学生集合包含以下文档:1
2
3
4
5
6
7
8
9{
"_id" : 5,
"quizzes" : [
{ "wk": 1, "score" : 10 },
{ "wk": 2, "score" : 8 },
{ "wk": 3, "score" : 5 },
{ "wk": 4, "score" : 6 }
]
}
下面的$push
操作将会:
- 使用
$each
修饰词来增加多个文档到quizzes数组中, - 使用
$sort
修饰词,按照score字段来降序排序修改过的quizzies数组中的全部元素, - 使用
$slice
修饰词,只保留quizzes数排中前三个排序过的元素。
1 | db.students.update( |
操作结果就是只保留了quizzes数组中分数最高的三个元素。1
2
3
4
5
6
7
8{
"_id" : 5,
"quizzes" : [
{ "wk" : 1, "score" : 10 },
{ "wk" : 2, "score" : 8 },
{ "wk" : 5, "score" : 8 }
]
}
上面操作中的修饰词都会被Mongodb自行处理,所有它们之间的书写顺序无关紧要。更多详情请见Modifiers。