MongoDB实战第二版笔记(8)第七章笔记

MongoDB实战第二版笔记(8)第七章笔记

  1、MongoDB更新数据库有两种实现:完整替换现有文档(update更新)或更新操作符修改文档(set操作符)。

  如何抉择?替换是更通用的做法。使用文档替换时,数据从表单提交,一旦验证,就可以传递给MongoDB;不管哪个字段被更新,代码执行的更新都是相同的。目标更新(set)通常获得更好的性能,因为不需要往返服务器获取并修改文档数据。最重要的是文档更新通常很小,如果通过替换更新,每个文档平均200KB大小,则每次更新要接受和发送200KB的数据。

  2、频繁使用目标更新意味着可以在序列化和传输数据上花费更少时间。

  3、目标操作允许原子更新文档,使用乐观锁来实现原子更新。使用原子更新,可以使用 $inc 来原子性修改计数器,即使大并发更新,每个 $inc 都会隔离操作,要么成功要么失败。【事实上所有发送给服务器的更新都是原子性的,基于每个文档进行隔离。更新操作符被原子性调用,因为这可以让查询和更新操作在单个操作内完成。】

  4、构建一个MongoDB对象的映射器来支持更新,就可通过替换实更新,这默认是合理的。绝大部分MongoDB对象映射器都使用这个策略。如果用户可以建模任意复杂的实体,然后通过替换来更新会比使用特定的更新操作符来更新简单得多。

  5、乐观锁或乐观并发控制,是一种确保干净更新数据但是不需要锁定数据的数据。举例wiki,多个用户同时更新,但不希望用户更新已过时页面。使用乐观锁协议,当用户保存修改,可以包含尝试更新时间戳,如果时间戳比最新保存的版本旧,就不允许更新。如果没有用户保存任何编辑页面,则允许更新。

  6、悲观锁,记录会在事务里第一次访问时被锁定,直到事务结束,在此期间,无法进行其他事务访问。

  7、MongoDB的findAndModify命令【命令随环境变换,ruby是find_and_modify,核心服务器会识别findandmodify】,允许在同一个往返过程中原子更新文档并返回它。原子更新就是一个不会被其他更新中断或者与其他操作交互的操作。

  如果用户在我们找到这个文档后修改之前尝试修改的文档,这个查找不会执行成功,原子更新会阻止这个情况,其他操作必须等待原子更新完成才行。

  8、每个MongoDB更新都是原子性,但与findAndModify不同,它会自动返回文档。有用在于,当要获取并更新一个文档(或更新并获取它)时,可能有另外一个MongoDB用户修改这个文档,虽然更新是原子性的,但很难知道更新文档的真实状态(更新前或者后),除非使用findAndModify。

  9、原子更新很重用,是因为其支持许多功能。例如,利用findAndModify构建工作队列和状态机,然后使用这些原始语句来构建事务语义,这极大地扩展了MongoDB的应用范围。

  10、findAndModify命令失败会返回nil,抛出InventoryFetchFailurey异常。如果是因为网络问题失败,抛出Mongo::OPerationFailure异常。

  11、MongoDB更新操作符

  • $inc来增加或减少一个数值,也可以添加或减去任意数值【发生在磁盘上,只影响指定值】
  • $set设置某个文档特定key值, $unset删除文档中提供的key,但是该命令对于数组却是设置数组元素的值为null而不是删除元素,要完全删除数组元素,则可以使用 $pull
  • rename修改key的名字或修改子文档名字
  • $SetOnInsert对应目的是只想新增数组而不修改数据。

  12、MongoDB数组更新操作符

  • $push是数组后面追加值,默认会在数组尾部添加单独元素
  • $pushAll添加多个值到数组上,但是过时方法
  • $each$push组合,可以在一次更新里添加多个更新
  • $slice目的是方便管理经常更新的数组。当向数组添加值而不想太大,则十分有用,但必须和$push以及$each操作符一起使用,允许裁短数组的大小、删除旧的值。传递给$slice的参数必须是小于或者等于0。这个参数的值是数组里允许的项目数量乘以-1。从2.6后可以传递正整数,会从数组尾部开始删除元素。
  • $sort帮助更新数组,因为有时候需要排序再删除
  • $addToSet会往数组后面添加值,但特殊在于,只会向数组里添加不存在的值【$each只能和$addToSet$push操作符一起使用】
  • $pop从数组中删除元素,会删除最后一个$push的项目。
  • $bit在单个二进制级别来执行逻辑运算。
  • $pull$pop的复杂形势,可以通过值指定要删除的元素。$pullAll则是同时删除多个元素。$pull强大的特性是可以传递查询作为参数来选择要拉取的元素。

  13、MongoDB允许通过原点选择器来定位要更新的元素。

  14、findAndModify的参数query、update、remove需要的:

  • query。查询选择器,默认为{}
  • update。指定更新的文档,默认为{}
  • remove。布尔值,若为true,则返回删除的对象。默认为false
  • new。布尔值,若为treue,则返回修改的文档。默认为false,返回最初的文档。
  • sort。指定排序方向。使用findAndModify一次酒删改一个文档,但该参数可以帮助控制哪个文档。例如,{created_at:-1}排序来处理最近创建的文档
  • fields。如果只要返回部分字段,就使用该参数指定,在处理大文档很有用。
  • upsert。布尔值,为true,则findAndModify作为upsert操作。如果文档不存在,则创建它。注意,如果要返回新创建的文档,则需要指定{new:true}。

  15、MongoDB3.0,WiredTiger存储引擎在集合级别,提供强大的文档级别的锁。

  16、更新文档的三种方式:

  • 最高效。只更新文档里的单个值并且BSON文档大小不会改变时才发送。通常发生在 $inc操作符中。 $inc只增加整数,磁盘的文档大小不会发生变化。
  • 修改文档大小和数据结构。使用 $push操作符修改文档,既增加文档的大小又修改结构。
  • 重写一个文档。如果文档扩大,但不能满足现在磁盘空间,则不仅仅需要重写,还需要移动到新的空间。如果移动操作经常发生,则会非常昂贵。MongoDB会动态调整集合分配预留空间的填充因子优化该问题。意味着当一个集合中许多的需要文档迁移更新时,内部预留空间的填充因子会增加。填充因子乘以每个插入文档的大小来获取额外空间。这也许能减少未来文档重新迁移的数量。MongoDB3.0使用2的幂作为MMAPv1存储默认的记录空间分配大小。

  17、操作符总结

操作符 作用
$inc 给定的值增加字段
$set 设置字段为给定的值
$unset 取消设置字段
$rename 重命名字段为给定的值
$setOnInsert 在upsert中,只在插入时设置字段
$bit 只执行按位更新字段

  18、数组操作符

数组操作符 作用
$ 根据查询选择器定位要更新的子文档
$push 添加值到数组中
$pushAll 添加数组到一个数组中
$addToSet 添加值到数组中,重复了也不处理
$pop 从数组中删除第一个或最后一个值
$pull 从数组中删除匹配查询条件的值
$pullAll 从数组中删除多个值

  19、数组运算修饰符

数组操作符 作用
$each $push$addToSet一起使用来操作多个值
$slice $push$each一起使用来缩小更新后的数组大小
$sort $push$each$slice一起来排序数组中的子文档

  20、隔离运算符

数组操作符 作用
$isolated 隔离其他操作,不允许其他操作交叉更新多个文档
发布了189 篇原创文章 · 获赞 675 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/YuYunTan/article/details/105472754
今日推荐