视频地址:MongoDB 教程四: 高级更改操作

db.collection.update()

说明

db.collection.update(query, update, options)

修改一个或多个集合中已经存在的文档记录。这个方法可以修改一个或多个已经存在的文档记录中的指定字段,或替换整个已经存在的文档记录,具体操作由传入的参数( update parameter)决定。

默认情况下, update() 方法只修改 一个 文档记录。设置 “Multi”选项 参数后可以批量更新匹配查询条件的所有文档记录。

The update() method has the following form:

在 2.6 版更改.

db.collection.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>}
)

The update() method takes the following parameters:

Parameter Type Description
query document The selection criteria for the update. Use the same query selectors as used in the find() method.
update document The modifications to apply. For details see Update方法的参数.
upsert boolean Optional. If set to true, creates a new document when no document matches the query criteria. The default value is false, which does not insert a new document when no match is found.
multi boolean Optional. If set to true, updates multiple documents that meet the query criteria. If set to false, updates one document. The default value is false. For additional information, see “Multi”选项.
writeConcern document

Optional. A document expressing the write concern. Omit to use the default write concern. See 安全的写操作.

2.6 新版功能.

在 2.6 版更改: The update() method returns an object that contains the status of the operation.

返回: 更新结果对象 ( 操作结果 )中包含本次操作的状态。

行为

安全的写操作

在 2.6 版更改.

The update() method uses the update command, which uses the default write concern. To specify a different write concern, include the writeConcern option in the options parameter. See 覆盖默认的写确认级别 for an example.

Update方法的参数

The update() method either modifies specific fields in existing documents or replaces an existing document entirely.

更新指定的字段

如果 <update> 参数中包含更新操作符( update operator ),也就是使用 $set 操作符时:

  • The <update> document must contain only update operator expressions.
  • The update() method updates only the corresponding fields in the document. For an example, see 更新指定的字段.

更新整个文档记录

如果 <update> 参数中 包含 field:value (普通的键值对)表达式,则:

  • The update() method replaces the matching document with the <update> document. The update() method does not replace the _id value. For an example, see 替换全部字段.
  • update() 方法 不会 批量替换文档( update multiple documents )。

更新插(Upsert) 选项

更新插(Upsert) 行为

如果 upsert 选项的值是 true 且没有匹配到查询条件的文档, update() 方法会插入 一条 文档记录。update方法会这样插入一条新文档记录:

  • 用传给 <update> 方法的参数,或者

  • 如果 <update> 方法传入的参数中 包含更新操作符( update operator )字段,会同时使用传入的 <query><update> 参数。update方法会用 <query> 参数的值创建一个基础文档记录,再把 <update> 参数中的值应用到这个文档记录中。

如果``upsert`` 选项的值是 true 并且匹配到符合查询条件的文档记录, update() 方法会执行更新操作。

参见

操作符 $setOnInsert

使用唯一索引

警告

如果想要避免插入多个同样的文档记录,当 query 参数的字段中有唯一索引时只要使用 upsert: true 选项即可。

如果 people 集合中没有 name 字段的值是 Andy 的记录,把这条记录插进去。要考虑多个用户同时使用下面的的 更新 操作并且都带了 upsert: true 这个选项的情况:

db.people.update({ name: "Andy" },{name: "Andy",rating: 1,score: 1},{ upsert: true }
)

如果所有的 update() 操作都完成了 query 这部分工作,但没有任何一个用户完成数据写入, 并且 name 字段上没有唯一索引,这时有可能每个 update 操作都插入了一个记录。

为了阻止 Mongodb 插入多条同样的文档记录,需要在 name 字段上创建一个唯一索引 ( unique index )。有了唯一索引,如果多个应用使用同样的包含 upsert: true 选项的更新操作, 只有一个 update() 操作可以成功插入一条新的文档记录。

其余的update操作会:

  • 更新最近插入的文档,或者

  • 尝试插入重复的记录时失败。

    如果因为出现重复的索引键而产生异常操作会失败,应用程序可以再次尝试这个操作,它会被转为更新操作并执行成功。

“Multi”选项

如果 multi 选项被设置成 trueupdate() 方法会更新所有 <query> 条件匹配到的文档记录。 multi 选项可以和其他读写操作符交叉使用。在未分片的集合中,可以使用独占操作符 ( $isolated )忽略批量更新操作, $isolated 操作会让当前更新操作使用独占模式,在操作完成前忽略其他操作。在独占操作进行时,其他使用者都看不到正在被更新的文档记录,直到操作完成或发生异常。

如果update参数 ( <update> )传入的文档参数中 包含 “键:值” 格式的数据(不包含其他操作符), update() 操作 不会 一次更新多条记录。

示例,参见 批量更新文档记录

分片集合

All update() operations for a sharded collection that specify the multi: false option must include the shard key or the _id field in the query specification. update() operations specifying multi: false in a sharded collection without the shard key or the _id field return an error.

参见

findAndModify()

示例

更新指定的字段

如果要修改文档中的指定字段,可以在 <update> 参数中使用更新操作符( update operators )。如果 <update> 参数中有文档中不存在的字段, update() 操作会在文档中加入这些字段。

示例,操作 books 集合并传入如下文档作为参数:

{ "_id" : 11, "item" : "Divine Comedy", "stock" : 2 }

下面的操作会在文档中增加 price 字段并把 stock 的值加 5

db.books.update({ item: "Divine Comedy" },{$set: { price: 18 },$inc: { stock: 5 }}
)

被更新过的文档如下:

{ "_id" : 11, "item" : "Divine Comedy", "price" : 18, "stock" : 7 }

参见

$set, $inc, Update Operators

更新子文档的字段

使用点号分隔法( dot notation )更新子文档中的字段。

示例,操作 books 集合并传入如下文档作为参数:

{ _id: 50, item: "TDB", stock: 0, isbn: { group: 11, publisher: 1111, title: 11, digit: 1 } }

下面的操作会更新 isbn 子文档中的 publisherdigit 字段:

db.books.update({ _id: 50 },{ $set: { "isbn.publisher": 2222, "isbn.digit": 0 } }
)

删除字段

下面的操作使用 $unset 操作符删除 stock 字段:

db.books.update( { _id: 11 }, { $unset: { stock: 1 } } )

参见

$unset, $rename, Update Operators

替换全部字段

books 集合中传入如下文档:

{"_id" : 22,"item" : "The Banquet","author" : "Dante","price" : 20,"stock" : 4
}

下面的操作给 <update> 参数传入一个只包含键值对的文档,表示用新的文档替换原有文档中的所有字段。这个操作 不会 替换 _id 的值。如果给 <query> 参数和 <update> 参数传入的文档的键和值完全相同,就表示没有需要修改的字段:

db.books.update({ item: "The Banquet" },{ item: "The Banquet", price: 19 , stock: 3 }
)

这个操作会创建如下新文档。这个操作会删除 author 字段并修改 pricestock 字段的值:

{"_id" : 22,"item" : "The Banquet","price" : 19,"stock" : 3
}

如果没有匹配的记录,插入一个新的文档记录

下面这个操作把更新插( upsert )选项设置成 true ,所以 update() 操作在 books 集合中找不到能匹配 <query> 参数的文档时会创建一个新的文档记录。

db.books.update({ item: "The New Life" },{ item: "The New Life", author: "Dante", price: 15 },{ upsert: true }
)

如果没有能匹配上 <query> 参数的文档, update 操作会用 <update> 参数传入的的文档参数创建一个新的记录,并给这个条记录的 _id 字段一个``ObjectId`` 类型的唯一值:

{"_id" : ObjectId("51e5990c95098ed69d4a89f2"),"author" : "Dante","item" : "The New Life","price" : 15
}

批量更新文档记录

使用批量更新文档记录需要把 multi 选项设置成 true 。例如,下面的操作会更新所有 stock 小于 5 的文档记录:

db.books.update({ stock: { $lt: 5 } },{ $set: { reorder: true } },{ multi: true }
)

覆盖默认的写确认级别

如果在一个副本集中把写确认级别( write concern )设置成 "w: majority" 并设置一个 5000 毫秒的 “超时时间” , 此操作会在副本集中的多数成员已经执行完操作或等待时间超过5秒时返回。

db.books.update({ stock: { $lt: 5 } },{ $set: { reorder: true } },{multi: true,writeConcern: { w: "majority", wtimeout: 5000 }}
)

联合使用 upsertupsert 选项:

创建一个包含如下文档记录的 books 集合:

{ _id: 11, author: "Dante", item: "Divine Comedy", price: 18, translatedBy: "abc123" }
{ _id: 12, author: "Dante", item: "Divine Comedy", price: 21, translatedBy: "jkl123" }
{ _id: 13, author: "Dante", item: "Divine Comedy", price: 15, translatedBy: "xyz123" }

命令中设置了 multi 参数来更新所有 item 字段值为 "Divine Comedy" 并且 author 字段值为 "Dante" 的记录。命令中设置 upsert: true ,当按上述条件匹配不到记录时会创建一个新的文档记录:

db.books.update({ item: "Divine Comedy", author: "Dante" },{ $set: { reorder: false, price: 10 } },{ upsert: true, multi: true }
)

下面的操作会更新所有匹配上的文档记录:

{ _id: 11, author: "Dante", item: "Divine Comedy", price: 10, translatedBy: "abc123", reorder: false }
{ _id: 12, author: "Dante", item: "Divine Comedy", price: 10, translatedBy: "jkl123", reorder: false }
{ _id: 13, author: "Dante", item: "Divine Comedy", price: 10, translatedBy: "xyz123", reorder: false }

如果集合中 没有 匹配到的记录,操作会变成插入一条记录:

{ _id: ObjectId("536aa66422363a21bc16bfd7"), author: "Dante", item: "Divine Comedy", reorder: false, price: 10 }

更新数组

更新指定位置的元素

如果想要更新一个数组字段中的一元素, update() 操作可以使用点号分隔法( dot notation )更新指定位置的数组元素。数组在mongodb中是最底层的数据类型。

下面的操作匹配 bios collection 集合中第一个 _id 字段的值等于 1 的文档记录,并更新数组字段 contribs 中的第二个元素:

db.bios.update({ _id: 1 },{ $set: { "contribs.1": "ALGOL 58" } }
)

更新一个未知位置的元素

如果不知道数组中的位置, update() 操作中可以使用位置操作符 $ 。为了定位要更新数组元素,这个数组字段必须出现在 <query> 参数中。

下面的操作在 bios collection 集合中查找第一个 _id 等于 3 并且 contribs 数组字段中包含 compiler 元素的文档记录。如果找到, update() 操作把文档中第一个匹配到的元素更新成 A compiler

db.bios.update({ _id: 3, "contribs": "compiler" },{ $set: { "contribs.$": "A compiler" } }
)

更新一个文档元素

The update() method can perform the update of an array that contains embedded documents by using the positional operator (i.e. $) and the dot notation.

下面这个例子查找 bios collection 集合中第一个 _id 字段等于 4awards 数组字段中嵌入文档的 by 字段等于 ACM 的文档记录。如果找到, update() 方法会更新第一个匹配到的嵌入文档中的 by 字段 :

db.bios.update({ _id: 4, "awards.by": "ACM"  } ,{ $set: { "awards.$.by": "Association for Computing Machinery" } }
)

添加一个元素

下面的操作查找 bios collection 集合中第一个 _id 等于 1 的文档记录并在 awards 数组字段中添加一个内嵌文档:

db.bios.update({ _id: 1 },{$push: { awards: { award: "IBM Fellow", year: 1963, by: "IBM" } }}
)

下一个例子,使用更新操作符( $set )和点号分隔法 dot notation 访问 name 嵌入文档中的 middle 字段。使用追加操作符 $push$push operator )在 awards 数组中添加一个嵌入文档。

思考下面的操作:

db.bios.update({ _id: 1 },{$set: { "name.middle": "Warner" },$push: { awards: {award: "IBM Fellow",year: "1963",by: "IBM"}}}
)

这个 update() 操作:

  • 修改 name 字段中包含子文档的记录。更新操作符( $set )修改 name 文档中的 middle 字段。使用点号分隔法( dot notation )访问内嵌文档中的字段。

  • awards 数字字段中添加一个元素。追加操作符( $push )会在 ``awards``字段中添加一个文档作为新元素。

操作结果

在 2.6 版更改.

操作成功

The update() method returns a WriteResult object that contains the status of the operation. Upon success, the WriteResult object contains the number of documents that matched the query condition, the number of documents inserted by the update, and the number of documents modified:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

参见

WriteResult.nMatched, WriteResult.nUpserted, WriteResult.nModified

写确认异常

如果 update() 操作遇到“写确认异常”,返回的结果中会包 WriteResult.writeConcernError 字段:

WriteResult({"nMatched" : 1,"nUpserted" : 0,"nModified" : 1,"writeConcernError" : {"code" : 64,"errmsg" : "waiting for replication timed out at shard-a"}
})

参见

WriteResult.hasWriteConcernError()

与写确认无关的异常

如果 update() 操作遇到一个与写确认无关的异常,返回结果中会包含 WriteResult.writeError 字段:

WriteResult({"nMatched" : 0,"nUpserted" : 0,"nModified" : 0,"writeError" : {"code" : 7,"errmsg" : "could not contact primary for replica set shard-a"}
})

参见

WriteResult.hasWriteError()

原文/转自:MongoDB 教程四: 高级更改操作

MongoDB 教程四: 高级更改操作相关推荐

  1. MongoDB 教程三: 高级查询 (SQL到MongoDB映射表)

    查询接口 对于查询操作,MongoDB 提供了 db.collection.find() 方法.这个方法接收查询条件和映射两个条件并且返回一个指向匹配文档的 游标 .你可以使用 limits, ski ...

  2. MongoDB 教程三: 高级查询

    视频:MongoDB 教程三: 高级查询 MongoDB支持的查询语言非常强大,语法规则类似于面向对象的查询语言,可以实现类似关系数据库单表查询的绝大部分功能,并且由于 MongoDB可以支持复杂的数 ...

  3. 8天学通MongoDB——第四天 索引操作

    原文:8天学通MongoDB--第四天 索引操作 这些天项目改版,时间比较紧,博客也就没跟得上,还望大家见谅. 好,今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性 ...

  4. 8天学通MongoDB——第四天 索引操作

    好,今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,通常我们 又会花费50%的时间在R上面,因为Read操作对用户来说是非常敏 ...

  5. narray删除列 python_Python数据分析入门教程(四):数值操作

    作者 | CDA数据分析师 我们把菜品挑选出来以后,就可以开始切菜了.比如要做凉拌黄瓜丝,把黄瓜找出来以后,那就可以把黄瓜切成丝了. 一.数值替换 数值替换就是将数值A替换成B,可以用在异常值替换处理 ...

  6. python实现将文件内容按照某一列内容的大小值重新排序_Python数据分析入门教程(四):数值操作...

    作者 | CDA数据分析师 我们把菜品挑选出来以后,就可以开始切菜了.比如要做凉拌黄瓜丝,把黄瓜找出来以后,那就可以把黄瓜切成丝了. 一.数值替换 数值替换就是将数值A替换成B,可以用在异常值替换处理 ...

  7. MongoDB 教程索引 (附有视频)

    MongoDB 教程索引 MongoDB 教程一: 安装和使用 (Mongodb启动命令mongod参数说明) MongoDB 教程二: 添加, 删除,查询 shell命令 MongoDB 教程三: ...

  8. TextSeek使用教程 (高级篇) - 文件搜索软件

    TextSeek使用教程 (高级篇) 上期初级篇介绍了TextSeek"简易模式"的用法.但是,简易模式虽然有免索引的优点,但它需要点击"搜索"后才解析文件,速 ...

  9. 黑马lavarel教程---5、模型操作(AR模式)

    黑马lavarel教程---5.模型操作(AR模式) 一.总结 一句话总结: AR: ActiveRecord :Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型 ...

最新文章

  1. 面试还在被红-黑树虐?看完这篇动图文章轻松反虐面试官
  2. C语言实现动态数组dynamic array(附完整源码)
  3. android studio 中 gradle 配置与说明
  4. 【模板】分散层叠算法(P6466)
  5. 精简linux操作系统,Tiny Core Linux—仅10多MB的精简Linux 操作系统发行版
  6. jQuery中.bind() .live() .delegate() .on()的区别
  7. eclipse各个版本下载
  8. 常年“盘踞”数据库前五的 MongoDB,在中国有哪些新动向?
  9. vba commondialog控件添加不上_MyVBA加载宏——添加自定义菜单03——功能分析
  10. jQuery实现tab选项卡
  11. 保存用户数据到mysql_MySQL中所有用户信息都保存在【 】数据表中。
  12. 【数据产品案例】美团外卖O2O的用户画像实践
  13. win7无法连接打印机拒绝访问_打印机拒绝访问,教您打印机拒绝访问无法连接
  14. 关于HTML的table表格换行一事
  15. 爬虫结合批量下载评书、有声书、戏曲等的使用教程
  16. 智能对话系统原理和实践
  17. 牛津博士讲大数据和量化金融
  18. requests.exceptions.SSLError: HTTPSConnectionPool(host=‘edith.xiaohongshu.com‘, port=443): Max retri
  19. 2022-12-01:从不订购的客户。找出所有从不订购任何东西的客户,以下数据的答案输出是Henry和Max,sql语句如何写? DROP TABLE IF EXISTS `customers`; C
  20. 通达信MACD面积背离指标公式,思路来自于缠论背驰

热门文章

  1. 高橋君とカード / Tak and Cards(AtCoder-2037)
  2. 线性结构 —— 单调栈与单调队列
  3. 基础算法 —— 高精度计算
  4. 信息学奥赛一本通C++语言——1131:基因相关性
  5. 信息学奥赛C++语言:旅行
  6. simpledateformat线程不安全_ArrayList为什么线程不安全?
  7. python循环练习_Python循环练习
  8. 语义分割论文阅读:FCN、PSPNet、DDRNet、BiseNet、BiseNetV2、deeplabv3
  9. 利用uiautomator2刷金币
  10. 剖析Caffe源码之Layer