zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

mongodb:更新、删除文档

MongoDB文档 删除 更新
2023-09-27 14:27:10 时间

语法

db.<collection>.update(<query>, <update>, <options>)
// <query> 筛选条件,同find的query
// <update> 更新的内容
// <options> 更新操作的参数
  • 不写第三个参数的时候,会用 <update> 文档完全替换查询出的文档
  • 当查询语句匹配到多个时候,只会修改第一个
// 第二个操作符<update>的一些说明:
// 更新操作符
{ $set: { <field1>: <value1>, ... } }
// 删除操作符
{ $unset: { <field1>: "", ... } }
// 重命名操作符
{ $rename: { <field1>: <newName1>, ... } }
// 加减操作符
{ $inc: { <field1>: <amount1>, ... } }
// 乘除操作符
{ $mul: { <field1>: <number1>, ... } }
// 最小
{ $min: { <field1>: <value1>, ... } }
// 最大
{ $max: { <field1>: <value1>, ... } }
// 数组操作符:
// 向数组字段中添加元素
{ $addToSet: { <field1>: <value1>, ... } }
// 数组字段中删除元素,1删除最后一个,-1删除第一个
{ $pop: { <field1>: <-1 | 1>, ... } }
// 数组删除特定的元素
{ $pull: { <field1>: <value | condition>, ... } }
{ $pullAll: { <field1>: [<value1>, <value2>, ...], ... } }
// 数组添加特定的元素
// 和$addToSet相似,但是$push 更强大
{ $push: { <field1>: <value1>, ... } }
// $position 将元素插入到数组指定位置
$position: <number>
// $sort 对数组进行排序,1正序小到大,-1倒叙大到小
$sort: <1 | -1>
// 截取部分数组
$slice: <number>
// 占位符
<array>.$
// 更新数组中所有元素
<array>.$[]
// 第三个操作符<options>的一些说明:
// 是否需要更新多个文档。因为默认情况下,即使我们筛选除了多个文档,update命令只会更新一篇文档
{ multi: <boolean> }
// 是更新还是新建,默认是false,当没有匹配到文档的时候,则不会进行任何操作。当我们设置为true,没匹配到则会创建新文档
{ upsert: <boolean> }
// save 命令,如果document里包含了_id字段,save()命令将会调用db.collection.update()命令并设置(upsert: true)
db.<collection>.save(<document>)
// remove 命令,删除文档
db.<collection>.remove(<query>, <options>)
// drop 命令,删除集合
db.<collection>.drop()

update例子

// 不写第三个参数的时候,会用 `<update>` 文档完全替换查询出的文档
db.accounts.update({ name: "Alue" }, { name: "Alue", balance: 120 })
// $set 新增字段info
db.accounts.update(
	{
		name: "jack"
	},
	{
		$set: {
			// 修改金额
			balance: 3000,
			// 新增的开户日期开户地点
			info: {
				dateOpened: new Date("2016-5-18T16:00:00Z"),
				branch: "branch1"
			}
		}
	}
)
// $set 修改字段,当字段为数组或者对象时,用点.运算符
// 当数组有2个,你想添加第3个元素时"contact.2": "aaa"
db.accounts.update(
	{
		name: "jack"
	},
	{
		$set: {
			// info 是对象,修改他的branch元素
			"info.branch": "branch2"
			// contact 是数组,修改第 1 项为aaa
			"contact.0": "aaa"
		}
	}
)
// $unset 删除jack的银行账户余额和开户地点
db.accounts.update(
	{
		name: "jack"
	},
	{
		$unset: {
			// 删除info.branch,这里的 "" 里面写啥都行,没有影响
			"info.branch": ""
			// 删除balance
			"balance": ""
		}
	}
)

$unset删除数组的一个元素时,数组长度不会变化,而是将那个元素变为null

// $rename 操作符修改 name 字段为 contact
db.accounts.update(
	{
		name: "jack"
	},
	{
		$rename: {
			"name": "contact"
		}
	}
)
// $rename 操作符修改字段的位置,把info.branch放到根目录,balance字段放到info里面
db.accounts.update(
	{
		name: "jack"
	},
	{
		$rename: {
			"info.branch": "branch",
			"balance": "info.balance"
		}
	}
)
// $inc 操作符使余额减去0.5
db.accounts.update(
	{
		name: "jack"
	},
	{
		$inc: {
			balance: -0.5
		}
	}
)
// $mul 操作符使余额乘0.5
db.accounts.update(
	{
		name: "jack"
	},
	{
		$mul: {
			balance: 0.5
		}
	}
)
// $min 操作符更新余额,如果balance字段小于5000那就保留原有值,如果不小于5000,则赋值为5000
db.accounts.update(
	{
		name: "jack"
	},
	{
		$min: {
			"balance": 5000
		}
	}
)

特殊情况:比如你用 $min 比较 null 和 5000,那么会判断 null 比较小,从而把余额更新为 null,具体比较规则如下
在这里插入图片描述

// $addToSet 操作符向contact数组中添加China
// 添加的新值重复的话,不会生效
// 插入多个 "contact": ["China", "US"]
db.accounts.update(
	{
		name: "jack"
	},
	{
		$addToSet: {
			"contact": "China"
		}
	}
)
// $addToSet、$each 操作符向contact数组中添加多个
db.accounts.update(
	{
		name: "jack"
	},
	{
		$addToSet: {
			"contact": {
				$each: ["China", "US"]
			}
		}
	}
)
// $pop 操作符向contact数组中删除最后一个元素
db.accounts.update(
	{
		name: "jack"
	},
	{
		$pop: {
			"contact": 1
		}
	}
)
// find + insert + forEach 将Karen的账户文档复制为Lawrence的账户文档
db.accounts.find(
	{
		name: "karen"
	},
	{
		id: 0
	}
).forEach(function(doc) {
	var newDoc = doc;
	newDoc.name = "lawrence";
	db.accounts.insert(newDoc)
})
// $pull 从karen 的联系方式中删除包含'hi'字母的元素
db.accounts.update(
	{
		name: "karen"
	},
	{
		$pull: {
			"contact": {
				$regex: /hi/
			}
		}
	}
)
// $pullAll 
{ $pull: { <field1>: { $in: [<value1>, <value2>] } } }
相当于
{ $pullAll: { <field1>: [<value1>, <value2>] } }

pullAll需要和源文档完全相同才会删除,pull 只要部分相同就会删除

// $push newArray 数组中添加内容
db.accounts.update(
	{
		name: "karen"
	},
	{
		$push: {
			"newArray": "new element"
		}
	}
)
// $push 和 $each 搭配使用,把2,3,4添加进newArray数组
// $position 从第0个开始插入,也就是首位
// $sort 正序排列
// $slice 从结尾开始数8个元素,其余删除掉
db.accounts.update(
	{
		name: "karen"
	},
	{
		$push: {
			newArray: {
				$each: [2, 3, 4],
				$position: 0,
				$sort: 1,
				// 可以只针对内嵌文档的某一个键来排序,比如键名为value
				$sort: { value: 1 },
				$slice: -8
			}
		}
	}
)

position,sort ,slice(执行顺序也是这个顺序) 必须和 $push $each 一起使用,如果只想使用 sort ,可以给 $each 传个空数组 []

// 利用数组占位符$,newArray.$ 中的 $ 就是代表筛选的元素
db.accounts.update(
	{
		name: "karen",
		newArray: "pos2"
	},
	{
		$set: {
			"newArray.$": "updated"
		}
	}
)
// 利用数组全改 $.[],contact数组中所有元素都被更新为88888
db.accounts.update(
	{
		name: "karen"
	},
	{
		$set: {
			"contact.$[]": "88888"
		}
	}
)

options例子

// 使用multi选项来更新多个符合筛选条件的文档
db.accounts.update(
	{},
	{
		$set: {
			"currency": "USD"
		}
	},
	{
		multi: true
	}
)

由于更新多个文档的操作虽然是在单一线程上执行的,如果这时有其他线程要操作数据库,更新的线程会被挂起,不一定能保证原子性,如果对原子性有严格要求,使用mongodb4.0 的事务

save例子

db.accounts.save(
	{
		_id: "account2",
		balance: 100
	}
)

remove删除文档

// 删除balance: 50的文档
db.accounts.remove(
	{
		balance: 50
	}
)

默认就是删除匹配所有的,update默认是更新一条

// 删除balance: 50的文档,只删除匹配的第一个
db.accounts.remove(
	{
		balance: 50
	},
	{
		justOne: true
	}
)
// 删除集合
// 一般先看自己在哪个集合
show collections
// 然后删除
db.accounts.drop()