mongodb3.2系统性学习——3、update()操作
- mongodb 包含众多的原子性操作:
实例:
//连接数据库 dbService = connect("localhost:27017"); //选择插入集合 db = dbService.getSiblingDB("jike"); //创建bulk对象用于批量插入 db.update_test.drop(); var bulk = db.update_test.initializeUnorderedBulkOp(); //测试数据 var doc1= { _id:1, name:"xiaoli", age:20, address: { province:"GuangDong", city:"ShenZhen" } } bulk.insert(doc1); var doc2= { _id:2, name:"xiaoli", age:20, address: { province:"GuangDong", city:"ShenZhen" } } bulk.insert(doc2); //下面执行插入操作 bulk.execute() print("========update - $set操作符的使用=======") /* { $set:{field1:value1,....} } set操组符用于修改一个字段的值,如果这个字段不存在的话,则会创建它。 注意:使用$set操作符一次可以更新文档的多个字段 */ var result = db.update_test.update( { name:"xiaoli" }, //更新条件 { //更新内容 $set: { "name":"xiaoli_update", "age":28 } } ,{multi:true} ); printjson( result ); var cursor = db.update_test.find({}); printjson(cursor.toArray())
print("========update - 不使用更新操作符=======") /* 如果update 的第二个参数不使用更新操作符,后面的文档会替换掉query返回的文档。 */ var result = db.update_test.update( {_id:1}, //更新条件 {age: 26 } //更新内容 ); printjson( result ); var cursor = db.update_test.find({}); printjson(cursor.toArray()) print("========update - $inc操作符的使用=======") /* {$inc:{"文档的键":待增加的值,....}} inc操作符用来增加(或减少)已有键的值,如果这个字段不存在的话,则会自动创建。 注意:1.$inc键的值必须为数字,只能用于整型、长整型或浮点数类型。 2.$inc键的值为负数的时,会减少已有键的值。 3.一次可以更新文档的多个字段 */ var result = db.update_test.update( {_id:1}, //更新条件 { //更新内容 $inc: { "age":2 } } ); printjson( result ); var cursor = db.update_test.find({}); printjson(cursor.toArray()) print("========update - $min操作符的使用=======") /* {$min:{filed1:value1,.....}} 如果$min操作符中value1的值小于使用query条件返回的文档中filed1字段对应值的话,就使用value1来替换原有文档的值; 如果使用query条件返回的文档中filed1字段的值不存在的话,就会用value1来创建该字段。 注意:一次可以更新文档的多个字段 */ var result = db.update_test.update( {_id:1}, //更新条件 { //更新内容 $min: { "age":16 } } ); printjson( result ); var cursor = db.update_test.find({}); printjson(cursor.toArray()) print("========update - $currentDate操作符的使用=======") /* { $currentDate:{<field1>:<typeSpecification1,...} } currentDate 操作符可以将filed1字段的值更新为当前的最新时间 主要用于记录操作的时间,支持Date和timestamp两种类型 默认时间用Date类型来表示,也可以通过使用$type操作符来显式的指定日期格式 隐式的:{$currentDate: { field1: true} } field1字段的值会被更新为Date类型时间 显式的:{$currentDate: { { $type: "date" } } 或者 {$currentDate: { { $type: "timestamp" } } 注意:1.使用$currentDate操作符 一次可以更新文档的多个字段 2.如果field指定的字段不存在的话,会自动创建 3.使用$currentDate操作符,主要用来记录操作时间 */ var result = db.update_test.update( {_id:1}, //更新条件 { //更新内容 $currentDate: { "optime_1":true, "optime_2":{$type:"timestamp"} } } ); printjson( result ); var cursor = db.update_test.find({}); printjson(cursor.toArray())
- 更新内嵌文档方式: 1修改整个内嵌文档。2 修改内嵌文档的某个字段。
//连接数据库 dbService = connect("localhost:27017"); //选择插入集合 db = dbService.getSiblingDB("jike"); //创建bulk对象用于批量插入 db.update_test.drop(); var bulk = db.update_test.initializeUnorderedBulkOp(); //测试数据 var doc1= { _id:1, name:"xiaoli", age:20, address: { province:"GuangDong", city:"ShenZhen" } } bulk.insert(doc1); //下面执行插入操作 bulk.execute() //测试查询 print("========update - 更新整个文档=======") /* {$set:{field1:value1,....}} */ var result = db.update_test.update( {_id:1}, //更新条件 { //更新内容 $set: { "address": { province:"Beijing",city:"ChaoYang" } } } ); printjson( result ); var cursor = db.update_test.find({_id:1}); printjson(cursor.toArray()) print("========update - 更新内嵌的文档的某些字段=======") /* {$set:{field1.field11:value1,....}} */ var result = db.update_test.update( {_id:1}, { $set: { "address.city":"GuangZhou" } } ); printjson( result ); var cursor = db.update_test.find({_id:1}); printjson(cursor.toArray())
- 更新数组元素 mongodb提供了很多特定操作符号,使得数组可以当成栈队列等有序对象使用 也可以 当成无序对象使用
实例:
//连接数据库 dbService = connect("localhost:27017"); //选择插入集合 db = dbService.getSiblingDB("jike"); //创建bulk对象用于批量插入 db.update_array_test.drop(); var bulk = db.update_array_test.initializeUnorderedBulkOp(); //测试数据 var doc1 = { name:"joe", scores:[60,60,61,62] } bulk.insert(doc1); var doc2 = { name:"jack", scores:[] } bulk.insert(doc2); ///下面执行插入操作 bulk.execute() print("========update - $占位符的使用=======") /* $占为符 用于表示第一个 满足query条件的 数组元素 在数组中的位置索引 从前向后数 db.collection.update( { <array>: value ... }, { <update operator>: { "<array>.$" : value } } ) */ var result = db.update_array_test.update( { name:"joe",scores:60 }, //更新条件 { //更新内容 $set: { "scores.$":90 } } ); printjson( result ); //测试一下执行结果 var cursor = db.update_array_test.find({name:"joe"}); printjson(cursor.toArray()) print("========update - $pop操作符的使用=======") /* $pop 用于从删除数组的头部(-1)或尾部(1)删除一个元素 当成对队列的形式 底下是 60 60 61 62 -1是最后一个 1是最后一个 { $pop: { <field>: <-1 | 1>, ... } } */ var result = db.update_array_test.update( { name:"joe"}, //更新条件 { //更新内容 $pop: { scores:1 } } ); printjson( result ); //测试一下执行结果 var cursor = db.update_array_test.find({name:"joe"}); printjson(cursor.toArray()) print("========update - $pull操作符的使用=======") /* $pull 删除数组中指定的元素 field1的参数可以是一个元素或者关系运算符 pull 一次可以删除 所有匹配的数组内的元素 { $pull: { <field1>: <value|query>, ... } } */ var result = db.update_array_test.update( { name:"joe"}, //更新条件 { //更新内容 $pull: { //scores:60 scores:{$gte:61} //使用关系运算符,删除大于等于61的分数 } } ); printjson( result ); //测试一下执行结果 var cursor = db.update_array_test.find({name:"joe"}); printjson(cursor.toArray()) print("========update - $pullAll操作符的使用=======") /* $pullAll 一次可以删除多个不同的元素 field1的参数是一个数组 { $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } } */ var result = db.update_array_test.update( { name:"joe"}, //更新条件 { //更新内容 $pullAll: { scores:[60,61] //删除第一个匹配name:joe的数组中所有包含scores为 60 跟 61 的所有元素 如果制定 multi:true的话 则会更新所有字段 } } ); printjson( result );
//实例
db.stores.update(
{ },
{ $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } },
{ multi: true }
)
//测试一下执行结果 var cursor = db.update_array_test.find({name:"joe"}); printjson(cursor.toArray()) print("========update - $push+$each操作符的使用=======") /* { $push: { <field1>: <value1>, ... } } { $push: { <field1>: { <modifier1>: <value1>, ... }, ... } } 注意: 1.如果fild1不存在的话,$push会自动为file1添加一个数组,并使用value1作为数组元素 2.如果待操作文档的filed1对应的字段值不是一个数组类型的值,执行失败,会抛错误异常。 3.如果value1是一个数组类型的值的话,push会将整个数组作为一个元素添加到fild1对应的数组中。 4.如果一次要添加多个元素的话,需要使用$push的$each修饰器。 */ var result = db.update_array_test.update( {name:"joe"}, //更新条件 { //更新内容 $push: { scores:80 } } ); //测试一下执行结果 var cursor = db.update_array_test.find({name:"joe"}); printjson(cursor.toArray()) var result = db.update_array_test.update( {name:"joe"}, //更新条件 { //更新内容 $push: { scores: { $each:[90,92,85], $slice:-4 //$position:1 //指定元素的插入位置 }, } } ); printjson( result ); //测试一下执行结果 var cursor = db.update_array_test.find({name:"joe"}); printjson(cursor.toArray())
//测试查询 print("========update - $push+$each+$sort+$slice操作符的使用=======") /* { $push: { <field1>: <value1>, ... } } { $push: { <field1>: { <modifier1>: <value1>, ... }, ... } } $each:可以一次插入多个数组元素 $sort:对数组元素按照指定字段进行排序 $slice:取数组元素的子集 $push与上面三个操作符联合使用,可以实现向数组中添加TopN元素 注意: 1.三个修改器的执行顺序:sort->slice->store 2.$sort和$slice $position必须要和$each结合使用 */ var result = db.update_array_test.update( {name:"jack"}, //更新条件 { //更新内容 $push: { scores: { $each:[ {"科目":"语文","成绩":80}, {"科目":"数学","成绩":95}, {"科目":"外语","成绩":70}, {"科目":"政治","成绩":60}, {"科目":"计算机","成绩":85} ], $sort:{"成绩":-1}, // 对数组进行降序排序 $slice:3 //Top 3 } } } ); printjson( result ); //测试一下执行结果 var cursor = db.update_array_test.find({name:"jack"}); printjson(cursor.toArray())
//$position 实例:
{ "_id" : 1, "scores" : [ 50, 60, 70, 100 ] }
db.students.update(
{ _id: 1 },
{
$push: {
scores: {
$each: [ 20, 30 ],
$position: 2
}
}
}
)
//结果:
{ "_id" : 1, "scores" : [ 50, 60, 20, 30, 70, 100 ]
下部是 很早之前的博客内容,多少有些帮助
首先看下:
> db.demo1.find({'name':'zhuang'}); { "_id" : ObjectId("569b85fcdd841753dc621f77"), "name" : "zhuang", "age" : 12, "sex" : "male" } > db.demo1.update({'name':'zhuang'},{'name':'zhaoxingzhuang'},0,1) WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 9, "errmsg" : "multi update only works with $ operators" } }) > db.demo1.update({'name':'zhuang'},{$set:{'name':'zhaoxingzhuang'}},0,1)
1、update()命令基本使用,( 默认只是更新一条符合查询条件的信息 默认情况下不存在不添加)
注意 单纯的使用db.user.update({"name":"user6"},{name:"user111"},0,1) 的情况下 会把符合查询条件{"namne":"user6"}的记录替换为一个新的字段信息 而应该使用$set,$inc等更新记录。
db.collection.update( criteria, objNew, upsert, multi ) //criteria : update的查询条件,类似sql update查询内where后面的 //objNew : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的 //upsert : 这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。 //multi : mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
事例:
db.test0.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } ); //只更新了第一条记录 db.test0.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true ); //全更新了 db.test0.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false ); //只加进去了第一条 db.test0.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true ); //全加进去了 db.test0.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );//全更新了 db.test0.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );//只更新了第一
$inc使用 {$inc:{"name":xx}} xx为整数表示递增 xx为负数表示递减 ,当字段不存在的时候会添加字段。
> db.user.find() { "_id" : ObjectId("54feead226be41dca9db0d24"), "name" : "wangping", "age" : 25, "sex" : "woman", "location" : { "city" : "beijing", "road" : "zhongguonongyedaxue" } } { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 24, "grade" : [ 1, 2, 5, 6 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } > db.user.update({},{$inc:{"age":10}},0,1) //年龄全部递增10岁 WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 }) > db.user.find() { "_id" : ObjectId("54feead226be41dca9db0d24"), "name" : "wangping", "age" : 35, "sex" : "woman", "location" : { "city" : "beijing", "road" : "zhongguonongyedaxue" } } { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 1, 2, 5, 6 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } >
2、$unset 使用 表示删除某个字段。
db.user.update({"name":"zhaoxingzhuang"},{$unset:{age:1},0,1}) //表示把符合条件的数据的age字段删除掉。
3、$push {$push:{arr:4}} $pushAll {$pushAll:{arr:[4,6,7]}} 如果字段不存在也会添加数组数据 只是针对数组操作
> db.user.find() { "_id" : ObjectId("54feead226be41dca9db0d24"), "name" : "wangping", "age" : 35, "sex" : "woman", "location" : { "city" : "beijing", "road" : "zhongguonongyedaxue" } } { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 1, 2, 5, 6 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } > db.user.update({},{$push:{grade:4}},0,1) //向grade数组中添加4 字段不存在的也会添加 WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 }) > db.user.find() { "_id" : ObjectId("54feead226be41dca9db0d24"), "name" : "wangping", "age" : 35, "sex" : "woman", "location" : { "city" : "beijing", "road" : "zhongguonongyedaxue" }, "grade" : [ 4 ] } { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 1, 2, 5, 6, 4 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } >
4、$pop 删除数组中的数值 db.a.update({"name":"zhuang"},{$pop:{arr:1}}) //arr:-1表示删除第一个 1 表示最后一个
> db.user.find({name:"gaofei"}) { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 1, 2, 5, 6, 4 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } > db.user.update({"name":"gaofei"},{$pop:{grade:1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find({name:"gaofei"}) { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 1, 2, 5, 6 ], "location" : { "province" : "shandong", "city" : "jiyang"
5、$addToSet 可以向数组中添加元素,与$push不同的是$addToSet会保证元素的唯一性,防止重复添加 $addToSet:{field:value} field不存在 则把value 赋值给数组,字段不为数组则会报错
$push $pushAll 字段不存在的时候会添加,而 $addToSet 报错
2015-03-18T21:19:28.201+0800 ReferenceError: sb is not defined > db.user.find() { "_id" : ObjectId("54feead226be41dca9db0d24"), "name" : "wangping", "age" : 35, "sex" : "woman", "location" : { "city" : "beijing", "road" : "zhongguonongyedaxue" }, "grade" : [ 4 ] } { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 2, 5, 6 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } > db.user.update({name:"gaofei"},{$addToSet:{grade:6}})//6没有添加进去 集合有唯一性 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 }) > db.user.find({name:"gaofei"}) { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 2, 5, 6 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } > db.user.update({name:"gaofei"},{$addToSet:{grade:8}})//8添加进去了 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find({name:"gaofei"}) { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "grade" : [ 2, 5, 6, 8 ], "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" } } >
6、$rename 字段信息重命名
> db.user.update({name:"gaofei"},{$rename:{grade:"testrename"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find({name:"gaofei"}) { "_id" : ObjectId("54feef3626be41dca9db0d25"), "name" : "gaofei", "age" : 34, "location" : { "province" : "shandong", "city" : "jiyang", "road" : "zuozhuangzhen" }, "testrename" : [ 2, 5, 6, 8 ] } >
7、关于$ 使用
> db.article.insert({title:"name",comment:[{by:"zhaoxingzhuang","vote":3},{by:"zgaofei","vote":6}]}) WriteResult({ "nInserted" : 1 }) > db.article.find() { "_id" : ObjectId("55098d395dc88907462c31e3"), "title" : "name", "comment" : [ { "by" : "zhaoxingzhuang", "vote" : 3 }, { "by" : "zgaofei", "vote" : 6 } ] } > db.article.update({title:"name"},{$inc:{comment.$.vote:1}}) 2015-03-18T22:41:28.828+0800 SyntaxError: Unexpected token . > db.article.update({title:"name"},{$inc:{"comment.$.vote":1}}) //提示出错 WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 16837, "errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: comment.$.vote" } }
看一下网友的
comment是一个array,但是不用遍历。用"$"就是解决办法。只是用错了。来看一下$到底什么意思。
update的前两个参数<查询条件>和<更新操作>中,如果你在<查询条件>中查询的内容是array里的内容,<更新操作>中就可以使用"$"来引用前查询中匹配到的元素。
你的第二个例子就是在查询一个array。在第一个例子里,你找到了title="name"
的doc, 这里匹配查询条件的不包含array. 实际上,你可以把两个例子中的的查询条件写在一起,查询 title="..."
,同时有zhaoxingzhuang留言的那个doc, 然后,把找到的这个zhaoxingzhuang的留言的投票+1.
> db.article.update({"title":"name","comment.by":"zhaoxingzhuang"},{$inc:{"comment.$.vote":1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.article.find() { "_id" : ObjectId("55098d395dc88907462c31e3"), "title" : "name", "comment" : [ { "by" : "zhaoxingzhuang", "vote" : 4 }, { "by" : "zgaofei", "vote" : 6 } ] } >
文档中:
Examples Update Values in an Array Consider a collection students with the following documents: { "_id" : 1, "grades" : [ 80, 85, 90 ] } { "_id" : 2, "grades" : [ 88, 90, 92 ] } { "_id" : 3, "grades" : [ 85, 100, 90 ] } To update 80 to 82 in the grades array in the first document, use the positional $ operator if you do not know the position of the element in the array: db.students.update( { _id: 1, grades: 80 }, //注意这个查询条件 数组中查询条件 { $set: { "grades.$" : 82 } } ) Remember that the positional $ operator acts as a placeholder for the first match of the update query document. Update Documents in an Array The positional $ operator facilitates updates to arrays that contain embedded documents. Use the positional $ operator to access the fields in the embedded documents with the dot notation on the $ operator. db.collection.update( { <query selector> }, { <update operator>: { "array.$.field" : value } } ) Consider the following document in the students collection whose grades element value is an array of embedded documents: { _id: 4, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] } Use the positional $ operator to update the value of the std field in the embedded document with the grade of 85: db.students.update( { _id: 4, "grades.grade": 85 }, { $set: { "grades.$.std" : 6 } } )
Update Embedded Documents Using Multiple Field Matches
The $ operator can update the first array element that matches multiple query criteria specified with the$elemMatch() operator.
Consider the following document in the students collection whose grades field value is an array of embedded documents:
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 90, mean: 85, std: 3 }
]
}
In the example below, the $ operator updates the value of the std field in the first embedded document that has grade field with a value less than or equal to 90 and a mean field with a value greater than 80:
db.students.update(
{
_id: 4,
grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
},
{ $set: { "grades.$.std" : 6 } }
)
This operation updates the first embedded document that matches the criteria, namely the second embedded document in the array:
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 6 },
{ grade: 90, mean: 85, std: 3 }
]
}
赞助我写出更好的博客