系列文章索引:
【Mongo】初步认识MongoDB shell
【Mongo】MongoDB文档查询
数据增删
插入 document
单条插入
insertOne()
方法可以向数据库中插入一条数据,效果如下:
> db.game.insertOne({name:"monster hunter: rise",orderDate:new Date(),price:298})
{
"acknowledged" : true,
"insertedId" : ObjectId("62ba565711721fa1455eb949")
}
此方法会为 document 自动添加一个_id
键,_id
也可以自己添加,比如这样:
> db.game.insertOne({name:"monster hunter: world",orderDate:new Date(),price:298,_id:1})
{ "acknowledged" : true, "insertedId" : 1 }
多条插入
insertMany()
方法可以向数据库中插入一个document
数组,效果如下:
> db.game.insertMany([{name:"bayonetta",company:"nintendo",price:318},{name:"nier replicant",company:"square enix",price:180},{name:"the king of fighters xiii",company:"snk corporation",price:28}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("62ba596511721fa1455eb94a"),
ObjectId("62ba596511721fa1455eb94b"),
ObjectId("62ba596511721fa1455eb94c")
]
}
insertMany()
方法默认为有序插入,可以通过指定第二个参数的形式允许 mongoDB 重新排列插入的顺序,来提高性能,使用方法如下:
> db.game.insertMany([
... {name:"fifa 22", price:63, platform:"switch"},
... {name:"animal crossing: new horizons", price:326, platform:"switch"},
... {name:"god of war", price:128, platform:"psn"},
... {name:"it takes two", price:99, platform:"steam"}
... ],{order:false})
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("62ba629011721fa1455eb94d"),
ObjectId("62ba629011721fa1455eb94e"),
ObjectId("62ba629011721fa1455eb94f"),
ObjectId("62ba629011721fa1455eb950")
]
}
如果在插入数据过程中发现中间某个数据错误(如:存在相同的_id
值),在有序插入中会立即中断程序,而在无序插入中会跳过此条文档,继续插入后边的数据。
注意:insertMany()
方法可以将多个document
插入到单个集合中。如果在数据导入的场景下,应该使用数据导入工具,因为 MongoDB 能够接受到的消息是有最大长度限制的(4.0.5 版本 MongoDB 最大消息长度是 48MB,如果超过限制,多数驱动程序会将其拆分为多个 48MB 的请求1)
删除操作
删除文档(document)
在 MongoDB 中删除文档可以使用方法deleteOne()
和deleteMany()
,使用方法如下:
> db.game.deleteOne({name:"fifa 22"})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.game.deleteMany({platform:"switch"})
{ "acknowledged" : true, "deletedCount" : 2 }
其中,deleteOne()
方法用于删除第一个符合条件的文档,deleteMany()
方法用于删除所有符合条件的文档。
注意:db.game.deleteMany({})
方法会删除集合中的所有文档,慎用
删除集合
drop()
方法可以用于删除一个集合,使用方法如下:
db.game.drop();
数据更新
MongoDB 针对更新操作提供了三个方法,分别是updateOne()
、updateMany()
和replaceOne()
。
其中,updateOne()
和updateMany()
用来对已有文档的更新操作,第一个参数为筛选条件,第二个参数为更改描述;replaceOne()
方法用于替换匹配的文档,第一个参数为筛选条件,第二个参数是用来替换的新文档。
替换文档
> db.game.replaceOne({_id:1},{name:"monster hunter: world",price:128,platform:"steam"})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
注意:在更新操作中最好使用_id
字段或其他唯一字段作为筛选条件,避免出现更新错误的问题
更新运算符
更新运算符是 MongoDB 内置的特殊键,可以用于指定复杂的更新操作,但是不能修改_id
的值。
$set
运算符
用于设置一个 key 的值,如果这个 key 不存在,则会创建一组对应的 k-v,使用方法为:
> db.game.updateOne({_id:1},{$set:{company:"capcon"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.updateOne({_id:1},{$set:{company:"capcom"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : "steam",
"company" : "capcom"
}
$set
运算符支持修改键的类型,如:
> db.game.updateOne({_id:1},{$set:{platform:["steam","psn","xbox"]}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam",
"psn",
"xbox"
],
"company" : "capcom"
}
$set
运算符同样支持修改内嵌文档中的数据,使用方式为:
> db.game.updateOne({_id:1},{$set:{company:{name:"capcom",region:"日本"}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam",
"psn",
"xbox"
],
"company" : {
"name" : "capcom",
"region" : "日本"
}
}
>
> db.game.updateOne({_id:1},{$set:{"company.region":"america"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam",
"psn",
"xbox"
],
"company" : {
"name" : "capcom",
"region" : "america"
}
}
$inc
运算符
$inc
运算符用来对数字类型的键进行递增操作,如果该键不存在,则会新建。使用方法如下:
> db.game.updateOne({_id:1},{$inc:{price:2}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 130,
"platform" : [
"steam",
"psn",
"xbox"
],
"company" : {
"name" : "capcom",
"region" : "america"
}
}
> db.game.updateOne({_id:1},{$inc:{score:5}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 130,
"platform" : [
"steam",
"psn",
"xbox"
],
"company" : {
"name" : "capcom",
"region" : "america"
},
"score" : 5
}
> db.game.updateOne({_id:1},{$inc:{score:-3}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 130,
"platform" : [
"steam",
"psn",
"xbox"
],
"company" : {
"name" : "capcom",
"region" : "america"
},
"score" : 2
}
注意:$inc 运算符只能操作整型、长整型、双精度浮点型三种类型的数据,如果用在其他类型,会报错。
数组运算符
$push
运算符
$push
运算符用于在数组末尾添加一个元素,如果数组不存在,则会自动创建并添加一条数据,以下代码用于在comments
数组中添加一条数据
db.game.updateOne(
{ _id: 1 },
{
$push: {
comments: { author: "tom", content: "it is very good" },
},
}
);
效果如下:
> db.game.updateOne({_id:1},{$push:{
... comments:{author:"tom",content:"it is very good"}
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "tom",
"content" : "it is very good"
}
]
}
$each
修饰符
$each
和$push
配合使用,可以在一次操作中添加多条数据,以下代码用来新增两条评论
db.game.updateOne(
{ _id: 1 },
{
$push: {
comments: {
$each: [
{ author: "link", content: "i can hunt everything" },
{ author: "salta", content: "link stop~~" },
],
},
},
}
);
效果如下:
> db.game.updateOne({_id:1},{$push:{
... comments:{$each:[
... {author:"link",content:"i can hunt everything"},
... {author:"salta",content:"link stop~~"}
... ]}
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "tom",
"content" : "it is very good"
},
{
"author" : "jerry",
"content" : "it is very very good"
},
{
"author" : "link",
"content" : "i can hunt everything"
},
{
"author" : "salta",
"content" : "link stop~~"
}
]
}
$slice
修饰符
$slice
修饰符能控制数组只增长到某个长度(如 5),可以防止数据增长过长。如果数组数量超过这个限制长度,则多余的数据不会插入。以下代码用于插入 2 条新评论并限制数组长度不能超过 5
db.game.updateOne(
{ _id: 1 },
{
$push: {
comments: {
$each: [
{ author: "kaiya", content: "shabby" },
{ author: "ying", content: "kaiya laji" },
],
$slice: 5,
},
},
}
);
效果如下:
> db.game.updateOne({_id:1},{$push:{
... comments:{
... $each:[
... {author:"kaiya",content:"shabby"},
... {author:"ying",content:"kaiya laji"}
... ],
... $slice:5
... }
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "tom",
"content" : "it is very good"
},
{
"author" : "jerry",
"content" : "it is very very good"
},
{
"author" : "link",
"content" : "i can hunt everything"
},
{
"author" : "salta",
"content" : "link stop~~"
},
{
"author" : "kaiya",
"content" : "shabby"
}
]
}
$sort
修饰符
$sort
用于在截断数组之前对数组进行排序,然后再保留对应的长度,以下代码用来插入后排序:
db.game.updateOne(
{ _id: 1 },
{
$push: {
comments: {
$each: [
{ author: "alix", content: "it`s so cool" },
{ author: "bill", content: "oh my god of war" },
],
$slice: 5,
$sort: { author: 1 },
},
},
}
);
效果如下:
> db.game.updateOne({_id:1},{$push:{
... comments:{
... $each:[
... {author:"alix",content:"it`s so cool"},
... {author:"bill",content:"oh my god of war"}
... ],
... $slice:5,
... $sort:{author:1}
... }
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "alix",
"content" : "it`s so cool"
},
{
"author" : "bill",
"content" : "oh my god of war"
},
{
"author" : "jerry",
"content" : "it is very very good"
},
{
"author" : "link",
"content" : "i can hunt everything"
},
{
"author" : "salta",
"content" : "link stop~~"
}
]
}
注意:不能将$sort
或$slice
修饰符单独与$push
使用,使用时必须有$each
存在
$addToSet
运算符
用于在添加数据时避免重复数据,用法如下:
db.game.updateOne(
{ _id: 1 },
{ $set: { comments: [{ author: "salta", content: "it`s so cool" }] } }
);
db.game.updateOne(
{ _id: 1 },
{
$addToSet: {
comments: { author: "salta", content: "it`s my like" },
},
}
);
效果如下:
> //comments数据设置为一条
> db.game.updateOne({_id:1},{$set:{comments:[{author:"salta",content:"it`s so cool"}]}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "it`s so cool"
}
]
}
> //插入一条新数据,新数据其中一个字段不同,可以正常插入
> db.game.updateOne({_id:1},{$addToSet:{
... comments:{author:"salta",content:"it`s my like"}
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "it`s so cool"
},
{
"author" : "salta",
"content" : "it`s my like"
}
]
}
> //插入和上一次一样的数据,这次不能正常插入,modifiedCount=0
> db.game.updateOne({_id:1},{$addToSet:{ comments:{author:"salta",content:"it`s my like"} }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "it`s so cool"
},
{
"author" : "salta",
"content" : "it`s my like"
}
]
}
$addToSet
运算符可以和$each
修饰符配合使用,来插入多条数据,使用方法和$push
运算符相同。
$pop
$pop
运算符可以从数据头部或尾部删除一个元素,具体用法如下:
//先添加数据
db.game.updateOne(
{ _id: 1 },
{
$push: {
comments: {
$each: [
{ author: "link", content: "hello salta" },
{ author: "xilia", content: "shabby" },
{ author: "ying", content: "oh my kong" },
],
},
},
}
);
//从头部删除数据
db.game.updateOne({ _id: 1 }, { $pop: { comments: -1 } });
//从末尾删除数据
db.game.updateOne({ _id: 1 }, { $pop: { comments: 1 } });
效果如下:
> db.game.updateOne({_id:1},{$push:{
... comments:{$each:[
... {author:"link",content:"hello salta"},
... {author:"xilia",content:"shabby"},
... {author:"ying",content:"oh my kong"}
... ]}
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "it`s so cool"
},
{
"author" : "salta",
"content" : "it`s my like"
},
{
"author" : "link",
"content" : "hello salta"
},
{
"author" : "xilia",
"content" : "shabby"
},
{
"author" : "ying",
"content" : "oh my kong"
}
]
}
> db.game.updateOne({_id:1},{$pop:{comments:-1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "it`s my like"
},
{
"author" : "link",
"content" : "hello salta"
},
{
"author" : "xilia",
"content" : "shabby"
},
{
"author" : "ying",
"content" : "oh my kong"
}
]
}
> db.game.updateOne({_id:1},{$pop:{comments:1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.updateOne({_id:1},{$pop:{comments:1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "it`s my like"
},
{
"author" : "link",
"content" : "hello salta"
}
]
}
$pull
$pull
用于删除数组中所有符合特定条件的元素,以下方法用来删除 comments 数组中含有author:"salta"
的所有元素:
db.game.updateOne({ _id: 1 }, { $pull: { comments: { author: "salta" } } });
效果如下:
> db.game.updateOne({_id:1},{$pull:{comments:{author:"salta"}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.findOne({_id:1})
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "link",
"content" : "hello salta"
}
]
}
注意:如上例所示,在使用$pull
运算符处理对象数组时,如果按对象的某一个属性删除,则只判断这一个属性是否符合条件,其他属性不参与判断
定位运算符($)
$
运算符用于对符合筛选条件的第一个文档进行修改,以下代码用于修改 document 的数组元素comments
中第一个author=link
的元素,改为author=salta
:
db.game.updateOne(
{ "comments.author": "link" },
{
$set: {
"comments.$.author": "salta",
},
}
);
运行效果如下:
> db.game.find({_id:1}).pretty()
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "link",
"content" : "hello salta"
}
]
}
> db.game.updateOne({"comments.author":"link"},{$set:{
... "comments.$.author":"salta"
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.find({_id:1}).pretty()
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "salta",
"content" : "hello salta"
}
]
}
如果已知修改元素在数组中的位置,可以通过数组下标对元素进行修改,以下代码用于对_id=1
的文档中comments
数组中的第一个元素进行修改:
db.game.updateOne(
{ _id: 1 },
{
$set: {
"comments.0.author": "xilia",
},
}
);
运行效果如下:
> db.game.updateOne({_id:1},{$set:{
... "comments.0.author":"xilia"
... }})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.find({_id:1}).pretty()
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "xilia",
"content" : "hello salta"
}
]
}
使用数组过滤器更新
MongoDB3.6 引入了数组过滤器arrayFilters
,可以在数组中筛选出符合条件的元素,并对其进行更新。以下代码用于对数组中的元素筛选出author="xilia"
的元素,并添加hidden=true
数据:
db.game.updateOne(
{ _id: 1 },
{
$set: {
"comments.$[item].hidden": true,
},
},
{ arrayFilters: [{ "item.author": "xilia" }] }
);
执行修改之前先添加测试数据:
> db.game.updateOne({_id:1},{$push:{comments:{$each:[{author:"salta"},{author:"link"},{author:"link"}]}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.find({_id:1}).pretty()
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "xilia",
"content" : "hello salta"
},
{
"author" : "salta"
},
{
"author" : "link"
},
{
"author" : "link"
}
]
}
运行效果如下:
> db.game.updateOne(
... {_id:1},
... {$set:{
... "comments.$[item].hidden":true
... }},
... {arrayFilters:[
... {"item.author":"xilia"}
... ]}
... )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.find({_id:1}).pretty()
{
"_id" : 1,
"name" : "monster hunter: world",
"price" : 128,
"platform" : [
"steam"
],
"comments" : [
{
"author" : "xilia",
"content" : "hello salta",
"hidden" : true
},
{
"author" : "salta"
},
{
"author" : "link"
},
{
"author" : "link"
}
]
}
upsert 更新
upsert
关键字用于updateOne()
或updateMany()
方法的第三个参数,第三个参数是一个选项文档,可以指定选项文档的操作。
upsert
表示如果能筛选到匹配的文档,则会对所有匹配的文档进行更新;如果更新筛选条件中找不到所匹配的文档,则会以筛选条件和更新内容为基础,创建一个新的文档。注意,这一流程是原子性的。以下为操作示例:
此操作表示name="god of war"
的游戏,涨价 30 元
db.game.updateOne(
{ name: "god of war" },
{
$inc: {
price: 30,
},
},
{ upsert: true }
);
运行效果如下:
> db.game.updateOne(
... {name:"god of war"},
... {$inc:{
... price:30
... }},
... {upsert:true}
... )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.game.find({name:"god of war"}).pretty()
{
"_id" : ObjectId("62ba629011721fa1455eb94f"),
"name" : "god of war",
"price" : 158,
"platform" : "psn"
}
删除此文档后再执行效果如下:
# 按名称查询,有一条结果
> db.game.find({name:"god of war"}).pretty()
{
"_id" : ObjectId("62ba629011721fa1455eb94f"),
"name" : "god of war",
"price" : 158,
"platform" : "psn"
}
# 删除此结果
> db.game.deleteOne({name:"god of war"})
{ "acknowledged" : true, "deletedCount" : 1 }
# 按名称查询,没有结果
> db.game.find({name:"god of war"}).pretty()
# 执行upsert更新
> db.game.updateOne( {name:"god of war"}, {$inc:{ price:30 }}, {upsert:true} )
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("62bd39540a71331919b6295e")
}
# 再次按名称查询,有一个新的文档
> db.game.find({name:"god of war"}).pretty()
{
"_id" : ObjectId("62bd39540a71331919b6295e"),
"name" : "god of war",
"price" : 30
}
$setOnInsert
运算符
此运算符表示,只有再插入文档数据时才会对字段进行设置,后续更新不会对该字段进行任何更改(类似于create_date
)。以下代码作用为:
当存在name="Nioh 2"
时以下代码更新失效,如果不存在,则会创建新的数据,新数据可以通过 $set
运算符更新,但不能通过$setOnInsert
运算符更新
db.game.updateOne(
{ name: "Nioh 2" },
{
$setOnInsert: {
published: new Date(),
},
},
{ upsert: true }
);
运行效果如下:
# 不存在数据的前提下,upsert更新
> db.game.updateOne(
... {name:"Nioh 2"},
... {$setOnInsert:{
... published:new Date()
... }},
... {upsert:true}
... )
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("62bd3d9f0a71331919b6297a")
}
# 查询结果,有一条是数据
> db.game.find({name:"Nioh 2"}).pretty()
{
"_id" : ObjectId("62bd3d9f0a71331919b6297a"),
"name" : "Nioh 2",
"published" : ISODate("2022-06-30T06:07:27.206Z")
}
# 继续按setOnInsert更新
> db.game.updateOne(
... {name:"Nioh 2"},
... {$setOnInsert:{
... published:new Date()
... }},
... {upsert:true}
... )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }
# 查询结果,时间没变化
> db.game.find({name:"Nioh 2"}).pretty()
{
"_id" : ObjectId("62bd3d9f0a71331919b6297a"),
"name" : "Nioh 2",
"published" : ISODate("2022-06-30T06:07:27.206Z")
}
# 按set更新
> db.game.updateOne( {name:"Nioh 2"}, {$set:{ published:new Date() }}, {upsert:true} )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
# 查询结果,更新成功
> db.game.find({name:"Nioh 2"}).pretty()
{
"_id" : ObjectId("62bd3d9f0a71331919b6297a"),
"name" : "Nioh 2",
"published" : ISODate("2022-06-30T06:08:30.014Z")
}
save()
辅助函数
save()
函数时一个 shell 函数。作用是,在文档不存在时插入文档,在文档存在时更新文档。如果文档中包含_id
键,save()
函数会执行一次 upsert,否则直接插入数据。用法如下:
db.game.save({
_id: 2,
name: "warm snow",
price: 38,
platform: "PC",
});
批量更新
批量更新函数updateMany()
和单个更新函数updateOne()
遵循相同的语法,唯一的区别是,updateMany()
将会更新所有匹配的文档,而updateOne()
只会更新第一个匹配到的文档。
数据修改后返回结果
findOneAndUpdate()
方法用于返回匹配的结果并更新数据,默认返回更新之前的数据,如果将第三个参数的returnNewDocument
属性设置为 true,可以返回更新之后的数据。注意,这个方法可以保证更新操作的原子性,在多线程环境中很实用。方法使用举例:
// 返回修改前的数据
db.game.findOneAndUpdate(
{ _id: 2 },
{
$set: {
platform: ["PC", "Steam"],
},
},
{ $sort: { name: -1 } }
);
// 返回修改之后的数据
db.game.findOneAndUpdate(
{ _id: 2 },
{
$set: {
platform: ["PC", "Steam"],
},
},
{
$sort: { name: -1 },
returnNewDocument: true,
}
);
运行结果如下:
> db.game.findOneAndUpdate(
... {_id:2},
... {$set:{
... platform:["PC","Steam"]
... }},
... {$sort:{name:-1}}
... )
{
"_id" : 2,
"name" : "warm snow",
"price" : 56,
"platform" : "PC",
"comments" : [
{
"author" : "salta",
"content" : "oh,is very googd"
}
]
}
> db.game.findOneAndUpdate(
... {_id:2},
... {$set:{
... platform:["PC","Steam"]
... }},
... {
... $sort:{name:-1},
... returnNewDocument:true
... }
... )
{
"_id" : 2,
"name" : "warm snow",
"price" : 56,
"platform" : [
"PC",
"Steam"
],
"comments" : [
{
"author" : "salta",
"content" : "oh,is very googd"
}
]
}
另外,findOneAndReplace()
方法和findOneAndUpdate()
方法的用法完全相同。findOneAndDelete()
方法用来返回删除之前的文档。
Shannon Bradshaw,Eoin Brazi,Kristina Chodorow.MongoDB 权威指南(第三版)[M]. 北京:人民邮电出版社出版,2020:25-26 ↩︎