将文档存入数据库后,可以使用以下几种方法对其进行更新:replaceOne、updateOne和updateMany。replaceOne将筛选文档作为第一参数,第二参数是用来替换匹配到的文档的新文档。updateOne、updateMany将筛选文档作为第一参数,变更文档作为第二参数,变更文档是对要进行的更改的描述。
1 replaceOne
replaceOne会用新文档对匹配到的文档进行完全替换:
db.集合名.replaceOne({键1:值1,···,键n:值n},新文档)
2 更新运算符
通常情况下文档只有一部分需要更新,所以可以使用更新运算符更新文档中的特定字段。更新运算符是一种特殊的键,可用于指定复杂的更新操作,比如更改、添加或删除键,甚至可以操作数组和内嵌文档。
2.1 $set修饰符
$set用来设置一个字段的值,如果该字段不存在则创建该字段。
db.集合名.updateOne({键1:值1,···,键n:值n},
{"$set":{键1:值1,···,键n:值n}})
$set不仅可以更改键值,也可以更改键的类型。
当不需要某个键时,可以用 $unset将这个键删掉:
db.集合名.updateOne({键1:值1,···,键n:值n},
{"$unset":{键1:值1,···,键n:值n}})
也可以用$set修改内嵌文档:
db.集合名.updateOne({键1:值1,···,键n:值n},
{"$set":{文档名.文档的键1:值1,···,文档名.文档的键n:值n}})
2.2 递增操作和递减操作
$inc运算符可以用来修改已存在的键值或者在该键不存在时创建它。对于更新分析数据、因果关系、投票或者其他有数值变化的地方,使用 $inc会很方便。
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$inc”:{键1:值1,···,键n:值n}})
如果要操作的键存在,那么会为该键的值增加相应的值;如果键不存在,则会创建该键并且将该键的值设置成相应的值。$inc是专门用来对数字进行递增和递减操作的,只能用于整型、长整型和双精度浮点型的值。
2.3 数组运算符
MongoDB中有一大类更新运算符用于操作数组。
2.3.1添加元素
如果数组已存在,$push会将元素添加到数组末尾;如果数组不存在,那么 $push就会创建该数组。
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$push”:{数组名1:{键1:值1,···,键n:值n},···,数组名n:{键1:值1,···,键n:值n}}})
这是$push的一种比较简单的使用方法,但也可以将它应用到更复杂的数组运算中。MongoDB查询语句为一些运算符提供了修饰符,其中就有 $push。
$each
使用$each修饰符可以在一次操作中添加多个值
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$push”:{数组名:{"$each":[值1,···,值n]}}})
$slice
如果只允许数组增长到某个长度,那么可以使用$slice修饰符配合 $each修饰符来防止数组增长到某个长度。
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$push”:{数组名:{"$each":[值1,···,值n],
"$slice":-n}}})
限制数组只包含最后加入的n个元素,如果数组元素数量小于n就保留所有元素,如果数组元素数量大于n就只保留最后n个元素。
$sort
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$push”:{数组名:{"$each":[值1,···,值n],
"$slice":-n,
"$sort":{键:1(升序)或-1(降序)}}}})
$sort会根据键字段的值对数组中的所有对象进行排序,然后保留前n个。注意,不能只将 $slice或 $sort与 $push配合使用,必须包含 $each
2.3.2将数组作为集合使用
$ne
db.集合名.updateOne({键1:{”$ne":值1}},
{“$push”:{键1:值1}})
如果值1不存在就添加。
$addToSet
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$addToSet”:{数组名:值}})
$addToSet可以和 $each结合使用进行批量添加不同的值,,而不能用 $ne和 $push结合来实现。
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$addToSet”:{数组名:{"$each":[值1,···,值n]}}})
2.3.3 删除元素
$pop
{"$pop":{"key":-1(从数组头部删除一个元素)/1(从数组尾部删除一个元素)}}
$pull
删除与给定条件匹配的所有元素。
db.集合名.updateOne({键1:值1,···,键n:值n},
{“$pull”:{数组名:值}})
2.3.4 基于位置的数组更改
当数组中有多个值,但我们只想修改其中一部分时,有两种方法可以操作数组中的值:按位置或使用定位运算符($字符)。
数组下标是从零开始的,可以将下标当作文档的键来表示元素:
数组名.x.键名
但是在很多情况下如果不预先查询文档就不知道我们要修改的元素的下标。为了解决这个问题,MongoDB提供了一个定位运算符$,它可以计算出查询文档匹配的数组元素并更新该元素:
db.集合名.updateOne({"数组名.键":值},
{"$运算符":{"数组名.$.键":值}})
定位运算符只会更新第一个匹配到的元素。
2.3.5 使用数组过滤器进行更新
MongoDB3.6引入了另一个用于更新单个数组元素的选项:arrayFilters。此选项可以修改与特定条件匹配的数组元素。
db.集合名.updateOne({键1:值1,···,键n:值n},
{运算符:{数组名.$[标识符].字段1:值1}},
{
arrayFilters:[{标识符.字段2:{条件}}]
})
标识符表示数组中所有匹配元素,如果标识符表示的元素的字段2代表的值满足条件,那么就在数组中添加一个名为字段1的字段,并将其值设为值1。
3upsert
upsert是一种特殊类型的更新。如果找不到与筛选条件匹配的文档,就会根据筛选条件和更新文档为基础创建一个文档;如果找到了匹配文档,则进行正常的更新。
db.集合名.update({},{},{"upsert":true})
有时需要在创建文档时对字段进行设置,但在后续更新时不对其进行修改。这就是$setOnInsert的作用,他只会在插入文档时设置字段的值。
db.集合名.update({},{"$setOnInsert":{"createAt":new Date()}},{"upsert":true})
save辅助函数
save是一个shell函数,它可以在一个文档不存在的时候插入文档,在文档存在的时候更新文档。如果文档中包含"_id"键,save就会执行upsert,否则就会执行插入操作。
db.集合名.save(表示文档的变量)
4 updateMany
db.集合名.updateMany()
用法与updateOne一致,但可以更新所有符合条件的文档。
5 返回被更新的文档
findOneAndUpdate
db.集合名.findOneAndUpdate({},{},{···"returnNewDocument":true(返回修改之后的文档)/false(返回修改之前的文档)})
findOneAndReplace
db.集合名.findOneAndReplace({},{},{···"returnNewDocument":true(返回替换之后的文档)/false(返回替换之前的文档)})
findOneAndDelete
db.集合名.findOneAndDelete({})
返回被删除的文档