MongoDB中数组类型的操作示例

58次阅读
没有评论

共计 5163 个字符,预计需要花费 13 分钟才能阅读完成。

自动写代码机器人,免费开通

这篇文章将为大家详细讲解有关 MongoDB 中数组类型的操作示例,丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

在 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,代表要删除数组中的最后一个元素。

2.2 操作案例

例如集合 students 中有以下文档:

{_id: 1, scores: [ 8, 9, 10] }

我们的需求是要把数组中的第一个元素(成绩为 8)移除,SQL 语句如下:

db.students.update({ _id: 1}, {$pop: { scores: -1} } )

更新后,文档如下

{_id: 1, scores: [ 9, 10] }

继续演示,如果在现有的基础上,我们需要进一步把数组的最后一个元素移除(成绩为 10),更新的 sQL 如下:

db.students.update({ _id: 1}, {$pop: { scores: 1} } )

查询结果 如下:

{_id: 1, scores: [ 9] }

3. $pull 操作符 3.1 语法及功能描述

$pull 是 $pop 的复杂形式。使用 $pull, 可以通过值精确指定要删除的元素。

语法格式

{$pull: { field1 : value|condition , field2 : value|condition , ...} }

3.2 操作案例 3.2.1 移除数组中等于指定值的元素

测试文档如下:

{
 _id: 1,
 fruits: [apples , pears , oranges , grapes , bananas],
 vegetables: [carrots , celery , squash , carrots]}
 _id: 2,
 fruits: [plums , kiwis , oranges , bananas , apples],
 vegetables: [broccoli , zucchini , carrots , onions]}

操作要求是将 数组字段 fruits 中的 apples and oranges 移除,还要将 vegetables 数组字段中的 carrots 移除,其更新语句如下:

db.stores.update({},
 {$pull: { fruits: { $in: [ apples , oranges] }, vegetables: carrots } },
 {multi: true}
)

更新后的结果如下:

{
 _id : 1,
 fruits : [pears , grapes , bananas],
 vegetables : [celery , squash]}
 _id : 2,
 fruits : [plums , kiwis , bananas],
 vegetables : [broccoli , zucchini , onions]}

此时,集合文档中,fruit 的数组字段 没有 apples 也没有 oranges,vegetables 数组字段也没有了 carrots。

3.2.2 移除数组中满足指定条件的元素

假如我们有一个 profiles 的集合,其文档格式如下:

{_id: 1, votes: [ 3, 5, 6, 7, 7, 8] }

我们要把 votes 大于等于 6 的元素移除,其语句如下:

db.profiles.update({ _id: 1}, {$pull: { votes: { $gte: 6} } } )

更新后的结果如下:

{_id: 1, votes: [ 3, 5] }

3.2.3 移除数组中内嵌子文档(即此时数组元素是子文档,每一个 {} 中的内容是一个数组元素)

假设我们有一个关于 调查的集合 survey,其数据如下:

{
 _id: 1,
 results: [{ item: A , score: 5},
 {item: B , score: 8, comment: Strongly agree} ]}
 _id: 2,
 results: [{ item: C , score: 8, comment: Strongly agree},
 {item: B , score: 4} ]}

需求是将 score 为 8 并且 item 为 B 的元素移除

db.survey.update({},
 {$pull: { results: { score: 8 , item: B} } },
 {multi: true}
)

更新后的文档如下:

{
 _id : 1,
 results : [{ item : A , score : 5} ]}
 _id : 2,
 results : [{ item : C , score : 8, comment : Strongly agree},
 {item : B , score : 4} ]}

3.2.4 如果数组类型的元素还内嵌一个数组(数组包数组),就要特别小心了。

此时就要用到 $elemMatch 操作符。

例如 文档格式如下:

{
 _id: 1,
 results: [{ item: A , score: 5, answers: [ { q: 1, a: 4}, {q: 2, a: 6} ] },
 {item: B , score: 8, answers: [ { q: 1, a: 8}, {q: 2, a: 9} ] }
 _id: 2,
 results: [{ item: C , score: 8, answers: [ { q: 1, a: 8}, {q: 2, a: 7} ] },
 {item: B , score: 4, answers: [ { q: 1, a: 0}, {q: 2, a: 8} ] }
}

需要将 results 数组字段 移除,移除的条件是 results 数组字段中的 answers 字段,符合  q 为 2 and a 大于等于 8。

db.survey.update({},
 {$pull: { results: { answers: { $elemMatch: { q: 2, a: { $gte: 8} } } } } },
 {multi: true}
)

更新后的数据如下:

{
 _id : 1,
 results : [{ item : A , score : 5, answers : [ { q : 1, a : 4}, {q : 2, a : 6} ] }
 _id : 2,
 results : [{ item : C , score : 8, answers : [ { q : 1, a : 8}, {q : 2, a : 7} ] }
}

4.$addToSet4.1 语法及功能描述

使用 $addToSet 也会往数组后面添加值,但是它比较特殊:它只会添加数组里不存在的值。

{$addToSet: { field1 : value1 , ...} }

4.2 操作案例

假如有一个集合 inventory   格式如下

{_id: 1, item: polarizing_filter , tags: [ electronics , camera] }

我们希望向向字段 tags 数组,添加一个元素 accessories,则更新语句如下:

db.inventory.update({ _id: 1},
 {$addToSet: { tags: accessories} }
)

更新后的结果为

{_id : 1, item : polarizing_filter , tags : [ electronics , camera , accessories] }

如果想批量的增加如果元素,我们可以结合 $each 操作符一起使用。

例如以下文档

{_id: 2, item: cable , tags: [ electronics , supplies] }

我们想在字段 tags 数组,添加元素 camera , electronics , accessories,则更新语句如下:

db.inventory.update({ _id: 2},
 {$addToSet: { tags: { $each: [ camera , electronics , accessories] } } }
 )

更新后的结果如下:

{
 _id: 2,
 item: cable ,
 tags: [electronics , supplies , camera , accessories]}

4.3 注意点

需要注意是,如果添加的元素是数组格式,则会将新添加的元素保留为数组(将会出现数组嵌套数组)

例如

{_id: 1, letters: [ a , b] }

执行的语句如下:

db.test.update({ _id: 1},
 {$addToSet: {letters: [ c , d] } }
)

查询结构显示为

{_id: 1, letters: [ a , b , [ c , d] ] }

关于 MongoDB 中数组类型的操作示例就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向 AI 问一下细节

丸趣 TV 网 – 提供最优质的资源集合!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-18发表,共计5163字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)