文档章节

MongoDB更新操作符(Update Operators).2nd

s
 sunsyu
发布于 2017/04/13 16:04
字数 2055
阅读 7
收藏 0

本文地址: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就是专门来增加(和减少)数字的。"$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”。  

  

 


  upsert

  upsert是一种特殊的更新操作,不是一个操作符。(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开始的。


  和update()一起使用:

  • 定位操作符("$")作为第一个匹配查询条件的元素的占位符,也就是在数组中的索引值。
  • 数组字段必须出现查询文档中。

  集合students中有两条文档:

{ "_id" : 1, "grades" : [ 78, 88, 88 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }

  执行下列语句创建集合文档数据:

db.students.remove();
db.students.insert({ "_id" : 1, "grades" : [ 78, 88, 88 ] });
db.students.insert({ "_id" : 2, "grades" : [ 88, 90, 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"},{$push:{"comments":{"name":"egger","content":"thks 2!"}}})

  

 

  $pull

语法:db.collection.update( { field: <query> }, { $pull: { field: <query> } } );

    pull pull操作符移除指定字段值为数组,且匹配pull语句声明的查询条件的所有元素。

复制代码
//插入一条文档
db.profiles.insert({ votes: [ 3, 5, 6, 7, 7, 8 ] });
//移除数组中所有元素7
db.profiles.update( { votes: 3 }, { $pull: { votes: 7 } } );
//移除数组中所有大于6的元素
db.profiles.update( { votes: 3 }, { $pull: { votes: { $gt: 6 } } } );

//Result
{ votes: [ 3, 5, 6, 8 ] }

{ votes: [ 3, 5, 6 ] }
复制代码

 

  

 

 

内容参考:

1.http://docs.mongodb.org/manual/reference/operator/

© 著作权归作者所有

s
粉丝 0
博文 109
码字总数 135924
作品 0
深圳
私信 提问
PHP-mongo-php-library使用

上文地址:https://www.jianshu.com/p/1de642b956f7 接下来,我就按照这个官方包来给大家演示一遍基本的curd,我附带上原生的mongodb语句,以便大家理解 注明:我用的MongoDB版本为3.4. 打开任意一...

DullCat
2018/05/16
0
0
MongooseJS 4.5.10 发布,MongoDB 连接包

MongooseJS 4.5.10 发布了。MongooseJS 是基于 node.js,使用 JavaScript 编程,连接 MongoDB 数据库的软件包,使MongoDB 的文档数据模型变得优雅起来,方便对 MongoDB 文档型数据库的连接和...

局长
2016/08/24
1K
0
MongooseJS 4.11.4 发布,MongoDB 连接包

MongooseJS 4.11.4 发布了,MongooseJS 是使用 JavaScript 编程,连接 MongoDB 数据库的软件包,使 MongoDB 的文档数据模型变的优雅起来,方便对 MongoDB 文档型数据库的连接和增删改查等常规...

两味真火
2017/07/24
567
0
mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、等等)

最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网:https://www.mongodb.com/ MongoDB 是一个基于分布式文件存储的...

Airship
2018/06/01
161
0
11-【MongoDB入门教程】MongoDB原子性和事务

在MongoDB中,写操作的原子性是在级别上的,即使修改的是文档中的内嵌部分,写锁的级别也是上。 当一个写操作要修改多个文档,每个文档的修改是原子性的。整个的写操作并不是原子性的,它可能...

jockchou
2015/07/03
2.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
446
10
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
4
0
spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
今天
3
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
7
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部