帮助中心/最新通知

质量为本、客户为根、勇于拼搏、务实创新

< 返回文章列表

【服务器相关】MongoDB中文档的更新操作示例详解

发表时间:2025-06-16 03:46:00 小编:主机乐-Yutio

前言

在MongoDB中,更新单个doc的操作是原子性的。默认情况下,如果一个update操作更新多个doc,那么对每个doc的更新是原子性的,但是对整个update 操作而言,不是原子性的,可能存在前面的doc更新成功,而后面的doc更新失败的情况。由于更新单个doc的操作是原子性的,如果两个更新同时发生,那么一个更新操作会阻塞另外一个,doc的最终结果值是由时间靠后的更新操作决定的。

我们在前面的文章中提到过文档的基本的增删改查操作,MongoDB中提供的增删改查的语法非常丰富,不清楚的朋友们可以参考这篇文章:#

那么下面的本文我们主要来看看更新都有哪些好玩的语法。

文档替换

假设我的集合中现在存了如下一段数据:

另外一个问题是更新时,MongoDB只会匹配第一个更新的文档,假设我的MongoDB中有如下数据:

使用修改器

很多时候我们修改文档,只是要修改文章的某一部分,而不是全部,但是现在我面临这样一个问题,假设我有如下一个文档:

MongoDB帮我把整个文档更新了!要解决这个问题,我们可以使用修改器。

$set修改器

$set可以用来修改一个字段的值,如果这个字段不存在,则创建它。如下:

如果该字段不存在,则创建,如下:

也可以利用$unset删除一个字段,如下:

$set也可以用来修改内嵌文档,还以刚才的书为例,如下:

注意:$slice的值为负数,运行结果如下:

{
“_id” : ObjectId(“59f042cfcafd355da9486008”),
“name” : “三国演义”,
“author” : {
“name” : “明代罗贯中”,
“gender” : “男”,
“age” : 100.0
},
“comments” : [
“111”,
“222”,
“333”,
“444”,
“555”
]
}

我们还可以在清理之前使用$sort对数据先进行排序,然后再清理比如我有一个class文档,如下:


{
“_id” : ObjectId(“59f07f3649fc5c9c2412a662”),
“class” : “三年级二班”
}

现在向这个文档中插入student,每个student有姓名和成绩,然后按照成绩降序排列,只要前5条数据,如下:


db.sang_collect.update({class:”三年级二班”},{$push:{students:{$each:[{name:”张一百”,score:100},{name:”张九九”,score:99},{name:”张九八”,score:98}],$slice:5,$sort:{score:-1}}}})

$sort的取值为-1和1,-1表示降序,1表示升序。

上面的命令执行两次之后(即插入两次),结果如下:


{
“_id” : ObjectId(“59f07f3649fc5c9c2412a662”),
“class” : “三年级二班”,
“students” : [
{
“name” : “张一百”,
“score” : 100.0
},
{
“name” : “张一百”,
“score” : 100.0
},
{
“name” : “张九九”,
“score” : 99.0
},
{
“name” : “张九九”,
“score” : 99.0
},
{
“name” : “张九八”,
“score” : 98.0
}
]
}

$slice和$sort不能只和$push一起使用,还要加上$each。

$addToSet

我们可以在插入的时候使用$addToSet,表示要插入的值如果存在则不插入,否则插入,如下:


db.sang_collect.update({name:”三国演义”},{$addToSet:{comments:”好书”}})

上面的命令执行多次之后,发现只成功插入了一条数据。也可以将$addToSet和$each结合起来使用,如下:


db.sang_collect.update({name:”三国演义”},{$addToSet:{comments:{$each:[“111″,”222″,”333”]}}})

$pop

$pop可以用来删除数组中的数据,如下:


db.sang_collect.update({name:”三国演义”},{$pop:{comments:1}})

1表示从comments数组的末尾删除一条数据,-1表示从comments数组的开头删除一条数据。

$pull

使用$pull我们可以按条件删除数组中的某个元素,如下:


db.sang_collect.update({name:”三国演义”},{$pull:{comments:”444″}})

表示删除数组中值为444的数据。

$

既然是数组,我们当然可以通过下标来访问,如下一行操作表示将下标为0的(第一个comments)comments修改为999:


db.sang_collect.update({name:”三国演义”},{$set:{“comments.0″:”999”}})

可是有的时候我并不知道我要修改的数据处于数组中的什么位置,这个时候可以使用$符号来解决:


db.sang_collect.update({comments:”333″},{$set:{“comments.$”:”333-1″}})

查询条件查出来333的下标,$符号就代码这个下标,然后通过$符号就能将之修改。

save

save是shell中的一个函数,接收一个参数,这个参数就是文档,如果文档中有_id参数save会执行更新操作,否则执行插入操作,使用save操作我们可以方便的完成一些更新操作。

类似于如下命令则表示一个插入操作(因为没有_id):


db.sang_collect.save({x:111})

好了,MongoDB的更新操作我们就先介绍这么多,有问题欢迎留言讨论。

参考资料:

1.《MongoDB权威指南第2版》

总结

本篇文章到此结束,如果您有相关技术方面疑问可以联系我们技术人员远程解决,感谢大家支持本站!


联系我们
返回顶部