NoSQL学习之路 (五):更新操作符(Update Operators).2nd
本文地址:http://www.cnblogs.com/egger/archive/2013/05/01/3053617.html 欢迎转载 ,请保留此链接??? ????! 通常文档只会有一部分要更新。利用原子的更新修改器,可以使得这种部分更新极为髙效。更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整、增加或者删除键,还可能是操作数组或者内嵌文档。 字段更新操作符 Field Update Operators$set"$set"用来指定一个键的值。如果这个键不存在,则创建它。 我们往下面的一条用户资料添加“兴趣”信息, db.users.insert({"name":"egger","age": 28,"sex" : "male"})
运行下面的代码,将该用户的兴趣设置为“读书”并添加至文档中(此时文档中“hobby”键是不存在,该条文档就会创建它): db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")}, {"$set" : {"hobby" :"read"}} )
当想更改用户的兴趣资料时,使用"$set" 然后将要更新的内容作为键“hobby”的值(下面的示例中将数组作为键值): db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$set" : {"hobby" :["swimming","basketball"]}} )
用"$set"甚至可以修改键的数据类型 db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$set" : {"sex" :1 }} ) 执行结果如下:
使用"$set"修改内嵌文档:
该文档中的作者信息为内嵌文档,我们将其内容全部更改: db.posts.update({"author.name":"egger"},{"$set":{"author.name":"mongo","author.age":18}})
$unset从文档中移除指定的键。 若要完全删除键“hobby”,使用“$unset”即可: db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$unset" : {"hobby" :1 }} )
$inc"$inc"修改器用来增加已有键的值,或者在键不存在时创建一个键。$inc就是专门来增加(和减少)数字的。"$inc"只能用于整数、长整数或双精度浮点数。要是用在其他类型的数据上就会导致操作失败。 例如毎次有人访问该博文,该条博文的浏览数就加1,用键"pageviews"保存浏览数信息。
下面使用"$inc”修改器增加"pageviews"的值 db.posts.update({"_id" : ObjectId("5180f1a991c22a72028238e4")},{"$inc":{"pageviews":1}})
上面执行update时如果将键值设置为n,那么就表示该键的值增加n(n可以为负数)。 db.posts.update({"_id" : ObjectId("5180f1a991c22a72028238e4")},{"$inc":{"pageviews":-100}})
$rename语法: {$rename: { <old name1>: <new name1>,<old name2>: <new name2>,... } } $rename操作符可以重命名字段名称,新的字段名称不能和文档中现有的字段名相同。 如果文档中存在A、B字段,将B字段重命名为A,$rename会将A字段和值移除掉,然后将B字段名改为A. 集合students中的一条文档数据: { "_id": 1,"nickname": [ "The American Cincinnatus","The American Fabius" ],"cell": "555-555-5555","name": { "first" : "george","last" : "washington" } } 将集合中"nickname"字段名重命名为“alias”、"cell"字段名重命名为"mobile": db.students.update( { _id: 1 },{ $rename: { 'nickname': 'alias','cell': 'mobile' } } )
执行下面的更新操作,集合中已存在name字段,将会删除“name”字段,将“alias”字段名重命名为“name” db.students.update( { _id: 1 },{ $rename: { "alias": "name" } } )
当重命名子文档字段名时需要使用"."操作符,格式:值为该子文档的字段名.子文档中字段名。 db.students.update( { _id: 1 },{ $rename: { "name.first": "name.fname" } } ) 执行上面的更新操作将name字段的值中first字段重命名为fname.
$rename操作符也可以将子文档中键值移到其他子文档中。 db.students.update( { _id: 1 },{ $rename: { "name.last": "contact.lname" } } ) 我们将名为name的子文档中的last字段,重名为“lname”,同时将其移动到子文档contact中,若contact字段不存在,数据库会新建该字段。
若指定的字段在集合中不存在,$rename操作符将不会有任何影响。 db.students.update( { _id: 1 },{ $rename: { 'wife': 'spouse' } } ) 若指定的多个字段在集合中都不存在,$rename操作符将不会有任何影响。 db.students.update( { _id: 1 },{ $rename: { 'wife': 'spouse','vice': 'vp','office': 'term' } } ) 集合中不存在上面语句中指定的wife、vice、office字段,所以上述的更新操作无任何影响。 若指定的多个字段中,有的在集合中存在,有的不存在,$rename操作符执行下列操作:
db.students.update( { _id: 1 },{ $rename: { 'wife': 'alias','mobile': 'cell' } } ) 执行上述更新操作,文档中只有“mobile”字段被替换为“cell”。
upsertupsert是一种特殊的更新操作,不是一个操作符。(upsert = up[date]+[in]sert) update() 方法的三个参数是upsert,这个参数是个布尔类型,默认是false。当它为true的时候,update方法会首先查找与第一个参数匹配的记录,在用第二个参数更新之,如果找不到与第一个参数匹配的的记录,就会以这个条件和更新文档为基础创建一个新的文档。如果找到了匹配的文档,则正常更新。upsert非常方便,不必预置集合,同一套代码可以既创建又更新文档。 db.users.remove() db.users.update({age :25},{$inc :{"age" :3}},true) db.users.findOne() 我们将users集合清空,执行upsert操作,查询出age字段值为25的文档,然后将该字段值增加3. 由于我们先清空了集合,所以update操作将执行insert操作,先创建一个键“age”的值为25的文档,然后在将这个值增加3,即键“age”的值为28,如图所示.
$setOnInsert当update方法使用upsert选项执行insert操作时,$setOnInsert操作符给相应的字段赋值。类似sql中update 语句的set。 db.collection.update( <query>,{ $setOnInsert: { <field1>: <value1>,... } },{ upsert: true } //{ upsert: true }可以用true替换 ) 示例:products集合无任何文档,执行下列语句,将插入一条文档"{ "_id" : 1,"defaultQty" : 100 }": db.products.update( { _id: 1 },{ $setOnInsert: { defaultQty: 100 } },{ upsert: true } )
若update方法执行的update操作而不是insert操作,那么$setOnInsert操作符将无效。 集合中有如下一条文档: { "_id" : 1, "defaultQty" : 100 } 下面的update方法将执行update操作: db.products.update( { _id: 1 },{ $setOnInsert: { defaultQty: 500,inStock: true },$set: { item: "apple" } },{ upsert: true } ) 更新结果,$setOnInsert没有任何影响。
数组更新操作符Array Update Operators只能用在键值为数组的键上的数组操作。 $ (query)语法: { "<array>.$" : value } 当对数组字段进行更新时,且没有明确指定的元素在数组中的位置,我们使用定位操作符("$")标识一个元素,数字都是以0开始的。
集合students中有两条文档: { "_id" : 1,"grades" : [ 78,88,88 ] }
{ "_id" : 2,"grades" : [ 88,90,92 ] }
执行下列语句创建集合文档数据: db.students.remove(); db.students.insert({ "_id" : 1,88 ] }); db.students.insert({ "_id" : 2,92 ] }); 执行下列操作: //查询匹配的文档中,数组有2个88,只更新第一个匹配的元素,也就是"grades.1" db.students.update( { _id: 1,grades: 88 },{ $set: { "grades.$" : 82 } }) ; //查询文档中没有出现grades字段,查询报错 db.students.update( { _id: 2 },{ $set: { "grades.$" : 82 } } );
"$push"修改器如果指定的键已经存在,会向已有的数组末尾加入一个元素,要是没有就会创建一个新的数组。 下面是一条文章内容的文档数据:
我们将使用"$push"对该文档添加一条评论信息。。 db.posts.update({"title":"MongoDB"},{$push:{"comments":{"name":"egger","content":"thks!"}}}) $push 没有使用双引号。文档将会增加一个"comments"(评论)键且键值是数组类型的。 继续添加一条评论信息,该信息将添加至键值数组的末尾。 db.posts.update({"title":"MongoDB"},"content":"thks 2!"}}})
$pull语法:db.collection.update( { field: <query> },{ $pull: { field: <query> } } ); $pull操作符移除指定字段值为数组,且匹配$pull语句声明的查询条件的所有元素。 //插入一条文档 db.profiles.insert({ votes: [ 3,5,6,7,8 ] }); //移除数组中所有元素7 db.profiles.update( { votes: 3 },{ $pull: { votes: 7 } } ); //移除数组中所有大于6的元素 db.profiles.update( { votes: 3 },{ $pull: { votes: { $gt: 6 } } } ); //Result { votes: [ 3,8 ] } { votes: [ 3,6 ] }
内容参考:1.http://docs.mongodb.org/manual/reference/operator/(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |