mongoDB对于文档的更新,既可以实现文档的更新,也可以实现文档随意的增减键(列),这是与传统的关系型数据库最大的不同之处,也就是所谓的无模式带来的一定程度上的便利。即mongoDB支持文档更新,也支持文档替换。本文给出了mongoDB更新语法及示例。
预备热身
Linux下快速安装MongoDB
Windows平台下安装MongoDB
mongoDB 启动与停止
mongo shell连接到mongoDB及shell提示符下执行js脚本
mongoDB简介及关键特性
SQL与mongoDB对比及映射
一、文档更新语法
db.collection.update(
<query>, //查询或过滤条件
<update>, //修改器(被修改键及内容)
{
upsert: <boolean>, //为true或者false,如果为true,未找到匹配文档则创建新文档
multi: <boolean>, //用于确定是单行还是更新所有行(true为所有行)
writeConcern: <document> //设定写关注,用于确保强一致性还是弱一致性
} //后面的3.2之后的语法参数基本相同
)
db.collection.updateOne( //仅3.2之后版本
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>
}
)
db.collection.updateMany( //仅3.2之后版本
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>
}
)
db.collection.replaceOne( //仅3.2之后版本,用于替换文档
<filter>,
<replacement>,
{
upsert: <boolean>,
writeConcern: <document>
}
)
更新相关事项
mongoDB中所有写操作是基于单个文档基本的原子性操作(3.2版本后)
_id类不支持更新,也不支持使用一个不同的_id文档进行替换
文档的更新可能会导致文档变大,会重新申请及分配新的磁盘空间
二、演示文档更新
1、db.collection.updateOne()
//演示环境
db.version()
3.2.9
//插入演示数据,此处略,参考:mongoDB文档查询 插入演示数据部分
//链接地址 http://blog.csdn.net/leshami/article/details/52901240
//下面查询favorites.artist值为Picasso的文档
> db.users.find({"favorites.artist": "Picasso"},
{finished:0,points:0,badges:0}).pretty()
{
"_id" : 1,
"name" : "sue",
"age" : 19,
"type" : 1,
"status" : "P",
"favorites" : {
"artist" : "Picasso",
"food" : "pizza"
}
}
{
"_id" : 6,
"name" : "abc",
"age" : 43,
"type" : 1,
"status" : "A",
"favorites" : {
"food" : "pizza",
"artist" : "Picasso"
}
}
//下面对favorites.artist值为Picasso的文档进行更新
//使用$set修改器来设置某个列的值,如下设置favorites.food的值pie,且type值为3
//使用$currentDate为新增的列lastModified设置当前日期
> db.users.updateOne(
{ "favorites.artist": "Picasso" },
{
$set: { "favorites.food": "pie", type: 3 },
$currentDate: { lastModified: true }
}
)
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
//查看更改后的文档结果
> db.users.find({"favorites.artist": "Picasso"},
{finished:0,points:0,badges:0}).pretty()
{
"_id" : 1, //这个文档已经被修改,且新增了列
"name" : "sue",
"age" : 19,
"type" : 3,
"status" : "P",
"favorites" : {
"artist" : "Picasso",
"food" : "pie"
},
"lastModified" : ISODate("2016-09-30T07:25:28.135Z")
}
{
"_id" : 6, //而_id为6的这个文档没有被修改,即updateOne方法仅更新一个文档
"name" : "abc",
"age" : 43,
"type" : 1,
"status" : "A",
"favorites" : {
"food" : "pizza",
"artist" : "Picasso"
}
}
2、db.collection.updateMany()
//下面更新favorites.artist值为Picasso的文档,
//更新的内容为favorites.artist值为Pisanello,type的值为3,且增加或修改lastModified字段
> db.users.updateMany(
{ "favorites.artist": "Picasso" },
{
$set: { "favorites.artist": "Pisanello", type: 3 },
$currentDate: { lastModified: true }
}
)
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 } //此处提示有2个匹配的文档,更新数为2
//再次查询favorites.artist值为Picasso的文档,其结果无任何文档返回,因为已经被更新
> db.users.find({"favorites.artist": "Picasso"},
... {finished:0,points:0,badges:0}).pretty()
//查询favorites.artist值为Pisanello的文档
> db.users.find({"favorites.artist": "Pisanello"},
... {finished:0,points:0,badges:0}).pretty()
{
"_id" : 1,
"name" : "sue",
"age" : 19, //Author : Leshami
"type" : 3, //Blog : http://blog.csdn.net/leshami
"status" : "P",
"favorites" : {
"artist" : "Pisanello",
"food" : "pie"
},
"lastModified" : ISODate("2016-09-30T08:00:47.826Z")
}
{
"_id" : 6,
"name" : "abc",
"age" : 43,
"type" : 3,
"status" : "A",
"favorites" : {
"food" : "pizza",
"artist" : "Pisanello"
},
"lastModified" : ISODate("2016-09-30T08:00:47.826Z")
}
3、db.collection.update()
//下面使用db.collection.update()方式更新
> db.users.update(
... { "favorites.artist": "Pisanello" },
... {
... $set: { "favorites.food": "pizza", type: 0, },
... $currentDate: { lastModified: true }
... }
... ) //此更新结果,如下行,nMatched为一个文档,nModified为1个文档,即仅更新一个文档
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) //等同于updateOne方法
> db.users.update(
... { "favorites.artist": "Pisanello" },
... {
... $set: { "favorites.food": "pizza", type: 0, },
... $currentDate: { lastModified: true }
... },
... { multi: true } //使用参数multi,且值为true
... ) //从返回的结果可知,更新文档数为2,即所有满足条件的文档都被更新
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 }) //等同于updateMany方法
//验证更新之后的结果
> db.users.find({"favorites.artist": "Pisanello"},
... {finished:0,points:0,badges:0}).pretty()
{
"_id" : 1,
"name" : "sue",
"age" : 19,
"type" : 0,
"status" : "P",
"favorites" : {
"artist" : "Pisanello",
"food" : "pizza"
},
"lastModified" : ISODate("2016-09-30T09:31:10.524Z")
}
{
"_id" : 6,
"name" : "abc",
"age" : 43,
"type" : 0,
"status" : "A",
"favorites" : {
"food" : "pizza",
"artist" : "Pisanello"
},
"lastModified" : ISODate("2016-09-30T09:31:10.524Z")
}
4、db.collection.replaceOne()
//替换前文档的内容(name:"abc")
> db.users.find({name:"abc"},{finished:0,points:0,badges:0}).pretty()
{
"_id" : 6,
"name" : "abc",
"age" : 43,
"type" : 1,
"status" : "A",
"favorites" : {
"food" : "pizza",
"artist" : "Picasso"
}
}
//下面使用db.collection.replaceOne()替换用户名为abc的文档,且替换了很多不同的键值
> db.users.replaceOne(
... { name: "abc" },
... { name: "amy", age: 34, type: 2, status: "P", favorites: { "artist": "Dali", food: "donuts" } }
... )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 } //这里提示有一个匹配,一个被更新
//验证替换后的结果
> db.users.find({name:"amy"},{finished:0,points:0,badges:0}).pretty()
{
"_id" : 6,
"name" : "amy",
"age" : 34,
"type" : 2,
"status" : "P",
"favorites" : {
"artist" : "Dali",
"food" : "donuts"
}
}
//使用db.collection.update方式可以实现相同的效果
> db.users.update(
... { name: "xyz" },
... { name: "mee", age: 25, type: 1, status: "A", favorites: { "artist": "Matisse", food: "mango" } }
... )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
三、小结
1、mongoDB文档更新有很多个不同的方法,传统的update,以及3.2版本之后的updateOne,updateMany
2、mongoDB文档替换也有很多个不通的方法,传统的update,以及3.2版本之后的replaceOnye,replaceMany
3、updateOne与updateMany是对update方法的扩展,update方法可以通过multi值为true或false来等同于updateMany以及updateOne
4、replaceOne与replaceMany也是对update方法的扩展,update方法可以通过multi值为true或false来等同于replaceMany以及replaceOne