MongoDB的CURD基本操作(二)——更新

注:本文基于MongoDB 4.2.6编写

1、更新

  • 替换更新
    比如将hello的值替换为basketball
> db.bb.find().pretty()
{ "_id" : ObjectId("5ec29c1e6b02bc57526eb598"), "hello" : "ball" }
> db.bb.update({hello: "ball"}, {hello: "basketball", hi: "rock"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "basketball",
	"hi" : "rock"
}

这种方式只能全文替换,无法单独替换某个字段,

> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "basketball",
	"hi" : "rock"
}
> db.bb.update({hello: "basketball"}, {hello: "basket"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{ "_id" : ObjectId("5ec29c1e6b02bc57526eb598"), "hello" : "basket" }

直接替换的话,hi字段也就被删除了,此时update执行的就是匹配第一个参数指定的文档,并将该文档替换为第二个参数的值。

  • set修改器
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "basketball",
	"hi" : "rock"
}
> db.bb.update({hello: "basketball"}, {$set: {hello: "ball"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock"
}

通过set修改器我们就能实现单独修改某个字段,当然也可以添加一些字段,甚至是数组和内嵌文档,

> db.bb.update({hello: "ball"}, {$set: {animal: "cat"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : "cat"
}
> db.bb.update({hello: "ball"}, {$set: {animal: ["cat", "dog", "fish"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"fish"
	]
}
> db.bb.update({hello: "ball"}, {$set: {animal: {"cat": 100, "dog": 90, "pig": 80}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 100,
		"dog" : 90,
		"pig" : 80
	}
}
> db.bb.update({hello: "ball"}, {$set: {"animal.cow": 200}})
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 100,
		"dog" : 90,
		"pig" : 80,
		"cow" : 200
	}
}

如果要修改内嵌文档的字段,可以如下操作,

> db.bb.update({hello: "ball"}, {$set: {"animal.cat": 110}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 110,
		"dog" : 90,
		"pig" : 80
	}
}

其中animal.cat记得加引号,否则会有以下报错,

> db.bb.update({hello: "ball"}, {$set: {animal.cat: 110}})
2020-05-19T09:44:14.652-0400 E  QUERY    [js] uncaught exception: SyntaxError: missing : after property id :
@(shell):1:44
  • unset修改器
    如果需要删除某个字段,可以使用unset修改器,
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 100,
		"dog" : 90,
		"pig" : 80,
		"cow" : 200
	}
}
> db.bb.update({hello: "ball"}, {$unset: {"hi": "rock", "animal.cat": 100, "animal.dog":90}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animal" : {
		"pig" : 80,
		"cow" : 200
	}
}
  • inc修改器
    主要用于数值增减,
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 110,
		"dog" : 90,
		"pig" : 80
	}
}
> db.bb.update({hello: "ball"}, {$inc: {"animal.cat": 110}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 220,
		"dog" : 90,
		"pig" : 80
	}
}
> db.bb.update({hello: "ball"}, {$inc: {"animal.pig": -50}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : {
		"cat" : 220,
		"dog" : 90,
		"pig" : 30
	}
}
  • push、pull数组修改器
    对于以下文档,如果我们要往animal里添加一个字段可如下操作,
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"fish"
	]
}
> db.bb.update({hello: "ball"}, {$push: {"animal": "fish"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"fish",
		"fish"
	]
}

如果要添加多个元素呢,

> db.bb.update({hello: "ball"}, {$push: {"animal": ["horse", "cow"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"fish",
		"fish",
		[
			"horse",
			"cow"
		]
	]
}

看起来是不行的,这时就要增加each修改器配合使用,

> db.bb.update({hello: "ball"}, {$push: {"animal": {$each: ["horse", "cow"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"fish",
		"horse",
		"cow"
	]
}

相反的,如果要删除元素就可以使用pull修改器,

> db.bb.update({hello: "ball"}, {$pull: {"animal": "cow"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"fish",
		"horse"
	]
}

如果要删除多个元素,这时就不能用each修改器了,要是用in修改器,

> db.bb.update({hello: "ball"}, {$pull: {"animal": {$in: ["horse", "fish"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog"
	]
}

对于pull有一点需要注意,它会删除所有匹配的元素,

> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"horse",
		"cow",
		"horse",
		"cow"
	]
}
> db.bb.update({hello: "ball"}, {$pull: {"animal": "cow"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"horse",
		"horse"
	]
}
  • addToSet修改器
    通过push增加元素会出现有重复元素的情况,如果想要避免该问题,可以使用addToSet修改器,
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog"
	]
}
> db.bb.update({hello: "ball"}, {$addToSet: {"animal": {$each: ["dog", "cow"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"hi" : "rock",
	"animal" : [
		"cat",
		"dog",
		"cow"
	]
}

注意:push、pull、addToSet修改器都是针对数组的操作。

  • rename修改器
    rename修改器用于字段的重命名,
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animal" : {
		"pig" : 80,
		"cow" : 200
	},
	"hi" : "rock"
}
> db.bb.update({hello: "ball"}, {$rename: {"hi": "happy", "animal": "animals"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animals" : {
		"pig" : 80,
		"cow" : 200
	},
	"happy" : "rock"
}
  • upsert
    有时候我们更新时希望未匹配到就创建该字段或者文档,这样就不用先确认是否存在,这时候就可以使用upsert设置,也就是update方法的第三个参数。 使用upsert可以保证原子性的修改。
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animals" : {
		"pig" : 80,
		"cow" : 200
	}
}
> db.bb.update({hello: "ball"}, {$inc: {"animals.dog": 50}}, {upsert: true})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animals" : {
		"pig" : 80,
		"cow" : 200,
		"dog" : 50
	}
}
  • 更新多个文档
    默认情况下,update只会修改匹配的第一个文档,如果想同时修改所有匹配的文档,就需要在update的第三个参数里增加multi设置,
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animals" : {
		"pig" : 80,
		"cow" : 200,
		"dog" : 50
	},
	"may" : "May"
}
{
	"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
	"hello" : "ball",
	"name" : "jan"
}
> db.bb.update({hello: "ball"}, {$set: {happy: "ending"}},{multi: true})
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
> db.bb.find().pretty()
{
	"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
	"hello" : "ball",
	"animals" : {
		"pig" : 80,
		"cow" : 200,
		"dog" : 50
	},
	"may" : "May",
	"happy" : "ending"
}
{
	"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
	"hello" : "ball",
	"name" : "jan",
	"happy" : "ending"
}

更多查询匹配规则可参考find命令。

  • updateOne()和updateMany()

这两个方法都可以用于更新文档,一个是只更新匹配的第一个文档,一个是更新所有匹配的文档,和update()的区别在于,update()支持explain(),但是updateOne()和updateMany()不支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值