MongoDB shell原子性更新修改器的应用

来源:互联网 发布:python idle设置 编辑:程序博客网 时间:2024/05/17 00:50

通常更新文档只会有一部分更新。可以使用update modifier指定对文档中的某些字段进行更新。它可以修改、增加、删除键,操作数组和内嵌文档。

1.$set修改器入门
mongos> db.blog.update({"address":{ "street":"haiyouStreet", "school":"fangzai" } },... {"$set":{"favorite book" :"War and Peace"}})//用$set添加键/值WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 20,                "weight" : 85        },        "username" : "nwn",        "favorite book" : "War and Peace"}mongos> db.blog.update({"address":{ "street":"haiyouStreet", "school":"fangzai" } }, {"$set":{"favorite book" :"Devil daddy"}})//更改favorite book的值WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 20,                "weight" : 85        },        "username" : "nwn",        "favorite book" : "Devil daddy"}mongos> db.blog.update({"address":{ "street":"haiyouStreet", "school":"fangzai" } }, {"$set":{"favorite book" :["Devil daddy","War and Peace"]}})//$set可以操作数组WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 20,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ]}mongos> db.blog.update({"username":"nwn"}, {"$set":{"sign.age":21}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//update函数第一个参数找到匹配对象,第二个参数的键会在匹配对象中自动检索并进行修改。mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ]}
2.$inc增加与减少

用来增加已有键值的值,或者改键不存在就创建一个。对于更新分析数据、因果关系、投票或者其他有变化数值的地方,使用这个都会非常方便。

mongos> db.blog.update({"username":"nwn"}, {"$set":{"score":0}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//当原数据不存在score键时,自动创建并赋值。mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ],        "score" : 0}mongos> db.blog.update({"username":"nwn"}, {"$inc":{"score":1}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ],        "score" : 1}mongos> db.blog.update({"username":"nwn"}, {"$inc":{"score":1000}})//为score键的值加1000WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ],        "score" : 1001}mongos> db.blog.update({"username":"nwn"}, {"$inc":{"username":1000}})WriteResult({        "nMatched" : 0,        "nUpserted" : 0,        "nModified" : 0,        "writeError" : {                "code" : 16837,                "errmsg" : "Cannot apply $inc to a value of non-numeric type. {_id: ObjectId('565fa32673c8340448fa4711')} has the field 'username' of non-numeric type String"        }})//“$inc”只能作用于整形、长整形或双精度浮点型值。要是在其他类型的数据上就会导致操作失败。
3.$push数组修改器

如果数组存在,$push会向已有的数组末尾加入一个元素,要是没有就创建一个新的胡祖。键的值默认存储为数组类型(很重要)。

mongos> db.blog.update({"username":"nwn"}, {"$push":{"comments":{"name":"zmk","email":"zmk1215211544@outlook.com","content":"nice post"}}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//默认存储类型为数组mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ],        "score" : 1001,        "comments" : [                {                        "name" : "zmk",                        "email" : "zmk1215211544@outlook.com",                        "content" : "nice post"                }        ]}mongos> db.blog.update({"username":"nwn"}, {"$push":{"comments":{"name":"A","email":"A@outlook.com","content":"nice post"}}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ],        "score" : 1001,        "comments" : [                {                        "name" : "zmk",                        "email" : "zmk1215211544@outlook.com",                        "content" : "nice post"                },                {                        "name" : "A",                        "email" : "A@outlook.com",                        "content" : "nice post"                }        ]}//再次插入,效果如上。
(1)$each
使用$each子操作符,可以通过一次$push操作添加多个值。
mongos> db.blog.update({"username":"nwn"}, {"$push":{"comments":{"$each":[1,2,3]}}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//通过each添加三个元素到comments的数组中成为其中的元素mongos> db.blog.findOne({"username":"nwn"}){        "_id" : ObjectId("565fa32673c8340448fa4711"),        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "sign" : {                "age" : 21,                "weight" : 85        },        "username" : "nwn",        "favorite book" : [                "Devil daddy",                "War and Peace"        ],        "score" : 1001,        "comments" : [                {                        "name" : "zmk",                        "email" : "zmk1215211544@outlook.com",                        "content" : "nice post"                },                {                        "name" : "A",                        "email" : "A@outlook.com",                        "content" : "nice post"                },                1,                2,                3//效果如左        ]}
(2)$ slice
值只能为负整数  数组的最大长度 保证数组不会超出设定好的最大长度。$slice:-10//如果数组的元素数量小于10($push之后),那么所有元素都将保留。如果数组的元素数量小于10,那么只有最后10个元素会保留。因此,“$slice”可以用来在文档中创建一个队列。
(3)$ sort
根据$sort指定的字段来进行排序  注意,不能只将"$slice"或"$sort"与"$push"配合使用,且必须使用"$each".
mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "zmk",                        "sorce" : 100                },                {                        "name" : "nwn",                        "sorce" : 99                },                {                        "name" : "mly",                        "socre" : 98                }        ]}//下面通过$slice 设置数组最大长度   通过$sort设置排序键/值  -1表示降序1表示升序mongos> db.blog.update({"age":20},{"$push":{"top3":{"$each": [ {"name":"haha","sorce":99},{"name":"heihei","sorce":98} ],"$slice":-3,"$sort":{"sorce":1}}}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "nwn",                        "sorce" : 99                },                {                        "name" : "haha",                        "sorce" : 99                },                {                        "name" : "zmk",                        "sorce" : 100                }        ]//效果如上,排序删除之后的效果}
4.$addToSet

想将数组作为数据集使用,保证数组中的所有元素不会重复。可以与$each一起使用,可以一次插入大量数据且不重复。

mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "nwn",                        "sorce" : 99                },                {                        "name" : "haha",                        "sorce" : 99                },                {                        "name" : "zmk",                        "sorce" : 100                }        ],        "emails" : [                "zmk@outlook.com",                "zmk@qq.com",                "zmk@163.com"        ]}mongos> db.blog.update({"age":20},{"$addToSet":{"emails":"zmk@qq.com"}})//再次向email属性添加相同元素WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "nwn",                        "sorce" : 99                },                {                        "name" : "haha",                        "sorce" : 99                },                {                        "name" : "zmk",                        "sorce" : 100                }        ],        "emails" : [                "zmk@outlook.com",                "zmk@qq.com",                "zmk@163.com"        ]        //结果如上,数组中的元素并没有重复。}
5 基于位置的数组修改器

示例如下:

mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "nwn",                        "sorce" : 99                },                {                        "name" : "haha",                        "sorce" : 99                },                {                        "name" : "zmk",                        "sorce" : 100                }        ],        "emails" : [                "zmk@outlook.com",                "zmk@qq.com",                "zmk@163.com"        ]}mongos> db.blog.update({"top3.0.name":"nwn"},{"$inc":{"top3.0.sorce":1}})//查找top3数组第一个元素属性name值为nwn的文档,并进行更新db.blog.update({"top3.name":"nwn"},{"$inc":{"top3.0.sorce":1}})//查找top3数组属性name值为nwn的文档,并进行更新//注意区分!!!!!!!!!!!!!!!!!!WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "nwn",                        "sorce" : 100                },                //更新完成效果如上。                {                        "name" : "haha",                        "sorce" : 99                },                {                        "name" : "zmk",                        "sorce" : 100                }        ],        "emails" : [                "zmk@outlook.com",                "zmk@qq.com",                "zmk@163.com"        ]}

很多情况下并不知道要修改的数组下标。为了克服这个困难,mongodb提供了“$”定位操作符,用来定位已经匹配的数组元素并进行更新。
示例如下:

mongos> db.blog.update({"top3.name":"nwn"},{"$set":{"top3.$.age":10}})//查找top3数组name属性为nwn的元素,并为此元素添加age键/值WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })mongos> db.blog.findOne({"name":"zmk"}){        "_id" : ObjectId("566004d173c8340448fa4712"),        "name" : "zmk",        "address" : {                "street" : "haiyouStreet",                "school" : "fangzai"        },        "age" : 20,        "weight" : 85,        "top3" : [                {                        "name" : "nwn",                        "sorce" : 102,                        "age" : 10                },                //结果如上                {                        "name" : "haha",                        "sorce" : 99                },                {                        "name" : "zmk",                        "sorce" : 100                }        ],        "emails" : [                "zmk@outlook.com",                "zmk@qq.com",                "zmk@163.com"        ]}
6 update的第三个参数、第四个参数

第三个参数和第四个参数的类型都为boolean类型。
第三个参数:(默认为false)为true:匹配文档若无,则自动创建新文档并进行update,被称之为upsert。
有时需要在创建文档的同时创建字段并为它赋值,但在之后的所有更新操作中,这个字段的值都不在改变,则可用“$setOnInsert”。可用于自定义时间戳的创建。

save函数只有一个参数(文档)。若此文档有“_id”值,这调用upsert。否则调用insert。

第四个参数:(默认为false)为true:则更新集合中全部匹配的文档。
运行之后可执行

db.runCommand({getLastError:1})//返回最后一次操作的相关信息
返回的键”n”的值就是更新的文档数量。

7.写入安全机制

简单来说,就是写入之后是否返回操作成功或失败的信息。分为应答式写入或非应答式写入。
驱动程序运用mongo或者collection类则是旧式非应答。
运用mongoclient则为应答式写入。
根据情况修改即可。

0 0
原创粉丝点击