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 }
  ]
}
 

 

posted @ 2015-03-13 20:54  timelesszhuang  阅读(3126)  评论(0编辑  收藏  举报