概述
在MongoDB的模式中,我们经常将一些数据存储到数组类型中,即我们常见的嵌套模式设计的一种实现方式。数组的这种设计实现方式在关系数据库中是没有或者说不常见的。所以,通过本文我们来梳理一下MongoDB的数组的相关操作。关于数组的操作可以分成两类,一类是数组操作符,另一个是数组运算修饰符。
数组操作符
操作符 | 实现功能 |
$ | 根据查询选择器定位要更新的文档 |
$push | 添加值到数组中 |
$pushAll | 添加数组到一个数组中。(将被$rach取代) |
$addToSet | 添加值到数组中,重复了也不处理 |
$pop | 从数组中删除第一个或者最后一个值。 |
$pull | 从数组中删除匹配查询条件的值。 |
$pullAll | 从数组中删除多个值。 |
数组运算修饰符
修饰符 | 实现功能 |
$each | 与$push和$addToSet一起使用来操作多个值。 |
$slice | 与$push和$each一起使用来缩小更新后数组的大小。 |
$sort | 与$push、$each、$slice一起来排序数组中的子文档。 |
1.$push操作符
1.1 语法及功能描述
$push 主要用来向数组中添加元素。
语法:
{ $push: { <field1>: <value1>, ... } }
默认情况下,它会在数组尾部添加一个单独的元素。
1.2 操作案例
假如我们有一个学生成绩的集合studentscore,其文档格式如下:
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 } ] } { "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 } ] }
其中的需求为,更新_id 为1的文档记录,在分数数组的字段上,添加 物理学的成绩,修改代码为
db.studentscore.update({_id:1},{$push: {score:{"physics":100}}})
修改后,结果查询如下:
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 }, { "physics" : 100 } ] } { "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 } ] }
1.3 结合$each修饰符,批量插入
如果一次将多个值添加到数组中,可结合 数组修改符 $each 一起使用。
例如,我们将小红的(_id =2)的物理成绩、化学成绩、生物成绩一起添加到文档中。执行的语句如下:
db.studentscore.update({ _id: 2 }, { $push: { score: { $each: [{ "physics": 100 }, { "chemistry": 90 }, { "biology": 99 }] } } } )
查询的结果如下:
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 }, { "physics" : 100 } ] } { "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 }, { "physics" : 100 }, { "chemistry" : 90 }, { "biology" : 99 } ] }
1.4 数组修饰符 $sort 和 $slice的使用
前面讲了$each 数组运算修饰符,那我们再举一个例子,将剩余的两个修饰符一起讲解了好了($sort 和 $slice)
例如,我们有文档记录如下:
{ "_id" : 5, "quizzes" : [ { "wk": 1, "score" : 10 }, { "wk": 2, "score" : 8 }, { "wk": 3, "score" : 5 }, { "wk": 4, "score" : 6 } ] }
现在我们,有个需求,就是 首先向文档的quizzes数组字段,追加三个记录,然后,我们再按照score排序,选取数组中的前三个元素。
db.students.update( { _id: 5 }, { $push: { quizzes: { $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], $sort: { score: -1 }, $slice: 3 } } } )
更新后的结果显示如下:
{ "_id" : 5, "quizzes" : [ { "wk" : 1, "score" : 10 }, { "wk" : 2, "score" : 8 }, { "wk" : 5, "score" : 8 } ] }
$slice操作修饰符是在MongoDB 2.4 里添加的,其目的是方便管理经常更新的数组。当向数组添加值但是不想数组太大的时候,这个操作符非常有用。它必须与$push、$each操作符一起使用,允许用来剪短数组的大小、删除旧的值。
与$slice操作修饰符很像,MongoDB 2.4 新增了$sort操作修饰符,帮助更新数组。当使用$push和$slice时,有时候要先排序再删除它们。
2. $pop 操作符
2.1 语法及功能描述
$pop操作符可以实现从数组中删除第一个或者是最好一个元素。
{ $pop: { <field>: <-1 | 1>, ... } }
参数为-1 ,代表要删除数组中的第一个元素;参数为1 ,代表要删除数组中的最后一个