MongoDB:mongodb修改器

x33g5p2x  于2022-03-04 转载在 Go  
字(13.2k)|赞(0)|评价(0)|浏览(305)

MongoDB:mongodb修改器

一、简介

​ 在mongodb中通常文档只会有一部分要更新,利用原子的更新修改器,可以做到只更新文档的一部分键值,而且更新极为高效,更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整、增加、或者删除键,还可以操作数组和内嵌文档。增加、修改或删除键的时候,应该使用$修改器。要把"foo"的值设备"bar",常见的错误做法如下:

db.coll.update(criteria,{“foo”:“bar”})

这种情况是不对的,实际上这种做法会把整个文档用{“foo”:“bar”}替换掉,一定要使用以$开头的修改器来修改键/值对。

二、修改器种类

$inc

修改器$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作

> db.user.save({"uid":"202203","type":"1",size:10})
WriteResult({ "nInserted" : 1 })

> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 10 }
> db.user.update({"uid" : "202203"},{"$inc":{"size" : 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 11 }
> db.user.update({"uid" : "202203"},{"$inc":{"size" : 2}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 13 }
> db.user.update({"uid" : "202203"},{"$inc":{"size" : -1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12 }

$set

用来指定一个键并更新键值,若键不存在并创建

> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12 }

# 给键不存在的时候赋值
> db.user.update({"uid":"202203","type":"1","size":12},{"$set":{"name":"zhangsan"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12, "name" : "zhangsan" }

# 给键存在的时候赋值
> db.user.update({"uid":"202203","type":"1","size":12},{"$set":{"name":"lisi"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12, "name" : "lisi" }

# 可改变键的值类型
> db.user.update({"uid":"202203","type":"1","size":12},{"$set":{"name":["java",".net","c++"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12, "name" : [ "java", ".net", "c++" ] }

# 对于内嵌文档
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12, "name" : [ "java", ".net", "c++" ] }
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 10, "width" : 5, "length" : 15 } }
> db.user.update({"name":"toyota"},{"$set":{"size.height":8}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12, "name" : [ "java", ".net", "c++" ] }
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } }

可见:对于内嵌文档在使用$set更新时,使用"."连接的方式。

$unset

从字面就可以看出其意义,主要是用来删除键

> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "size" : 12, "name" : [ "java", ".net", "c++" ] }
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } }

> db.user.update({"uid" : "202203","type" : "1"},{"$unset":{"size":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1", "name" : [ "java", ".net", "c++" ] }
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } }

> db.user.update({"uid" : "202203","type" : "1"},{"$unset":{"name":0}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203", "type" : "1" }
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } }

> db.user.update({"uid" : "202203","type" : "1"},{"$unset":{"type":-1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c5b308f967a1701d89d2"), "uid" : "202203" }
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } }

使用修改器$unset时,不论对目标键使用1、0、-1或者具体的字符串等都是可以删除该目标键

upsert

upsert是一种特殊的更新。当没有符合条件的文档,就以这个条件和更新文档为基础创建一个新的文档,如果找到匹配的文档就正常的更新

使用upsert,既可以避免竞态问题,也可以减少代码量(update的第三个参数就表示这个upsert,参数为true时)

> db.user.find()
{ "_id" : ObjectId("6220d4a308f967a1701d89d5"), "size" : 11 }

> db.user.save({"size":11},{$inc:{"size":3}})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220d4a308f967a1701d89d5"), "size" : 11 }
{ "_id" : ObjectId("6220d4be08f967a1701d89d6"), "size" : 11 }

> db.user.update({"size":11},{$inc:{"size":3}},false)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220d4a308f967a1701d89d5"), "size" : 14 }
{ "_id" : ObjectId("6220d4be08f967a1701d89d6"), "size" : 11 }

> db.user.update({"size":11},{$inc:{"size":3}},true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220d4a308f967a1701d89d5"), "size" : 14 }
{ "_id" : ObjectId("6220d4be08f967a1701d89d6"), "size" : 14 }

save函数

可以在文档不存在的时候插入,存在的时候更新,只有一个参数文档

要是文档含有"_id",会调用upsert。否则,会调用插入

> db.user.find()
{ "_id" : ObjectId("6220d63b08f967a1701d89d7"), "name" : "lisi", "age" : "23" }

> db.user.save({"_id":ObjectId("6220d63b08f967a1701d89d7"),"name":"zhangsan"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find()
{ "_id" : ObjectId("6220d63b08f967a1701d89d7"), "name" : "zhangsan" }

数组修改器 – $push

$push–向文档的某个数组类型的键添加一个数组元素,不过滤重复的数据。添加时键存在,要求键值类型必须是数组;键不存在,则创建数组类型的键

> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } }

# 先push一个当前文档中不存在的键title
> db.user.update({"name":"toyota"},{$push:{"title":"t1"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t1" ] }

# 再向title中push一个值
> db.user.update({"name":"toyota"},{$push:{"title":"t2"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t1", "t2" ] }

# 再向title中push一个值
> db.user.update({"name":"toyota"},{$push:{"title":"t2"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t1", "t2", "t2" ] }

数组修改器-- $pop$pull

$pop从数组的头或者尾删除数组中的元素

> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t1", "t2", "t2", "t3", "t4" ] }

# 从数组的尾部删除 1
> db.user.update({"name":"toyota"},{$pop:{"title":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t1", "t2", "t2", "t3" ] }

# 从数组的头部 -1
> db.user.update({"name":"toyota"},{$pop:{"title":-1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t2", "t2", "t3" ] }

$pull从数组中删除满足条件的元素

> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t2", "t2", "t3" ] }

> db.user.update({"name" : "toyota"},{$pull:{"title":"t2"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220c9ee08f967a1701d89d3"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 }, "title" : [ "t3" ] }

数组的定位修改器

在需要对数组中的值进行操作的时候,可通过位置或者定位操作符("$").数组是0开始的,可以直接将下标作为键来选择元素

> db.user.find()
{ "_id" : ObjectId("6220d21608f967a1701d89d4"), "uid" : "001", "comments" : [ { "name" : "t1", "size" : 10 }, { "name" : "t2", "size" : 12 } ] }

> db.user.update({"uid":"001"},{$inc:{"comments.0.size":11}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("6220d21608f967a1701d89d4"), "uid" : "001", "comments" : [ { "name" : "t1", "size" : 21 }, { "name" : "t2", "size" : 12 } ] }

相关文章