持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
base
BASE 操作可以理解为:基本可用(BA)、软状态(S)、最终一致性(E)。
- 基本可用(BasicallyAvailable) :NoSQL 允许分布式系统中某些部分出现故障,系统的其余部分依旧可以继续运行。它不会像 ACID 那样,在系统出现故障时,进行强制拒绝,继续允许部分访问。
- 软状态(Soft State) :NoSQL 在数据处理过程中,允许在这个过程中,存在数据状态暂时不一致的情况,最红会经过纠错处理,达成一致的。
- 最终一致性(Eventually Consistent) :NoSQL 的软状态允许,数据处理过程状态的暂时不一致,但是最终经过处理,结果将是一致的。
原子性
建数据库 test 和集合 q1,同时给集合中添加一些数据。
use test
db.q1.insert([
{_id: "10001",cname: "《Java 程序设计基础》",price: 50.0,amount: 10,unit: "元",recordtime: ISODate("2021-11-03"),flag: false,checkout: [{by:"lisi",enddate: ISODate("2021-11-03")}]},
{_id: "10002",cname: "《C 语言程序设计》",price: 30.0,amount: 1,unit: "元",recordtime: ISODate("2021-11-04"),flag: false,checkout: [{by:"wangwu",enddate: ISODate("2021-11-04")}]},
{_id: "10003",cname: "《Python 程序设计》",price: 60.0,amount: 10,unit: "元",recordtime: ISODate("2021-10-03"),flag: true,checkout: [{by:"yangguo",enddate: ISODate("2021-10-03")}]}
])
✨ 说明:
_id字段可以自己指定,如果自己不指定,添加文档时系统会随机给定一个类型为 ObjectID 的值。
MongoDB 中所谓的原子操作就是要么这个文档保存到 MongoDB 数据库,要么没有保存到 MongoDB 数据库,不会出现查询到的文档是没有保存完整的情况。MongoDB 提供了许多原子操作,比如文档的保存、修改、删除等。
如果要实现原子性修改功能,需要依赖方法:db.collection.findAndModify(),此方法的执行分为两步:find 和 update,属于 get-and-set 方式操作,它的功能强大之处在于可以保证操作的原子性。它可以很方便执行查询以及其他需要取值和赋值风格的原子性操作,使其可以实现一些简单的类似事务的操作。
findAndModify() 方法的语法:
db.Collection.findAndModify(
{
query:<document>,
sort:<document>,
update:<document>,
new:<boolean>,
fields:<document>,
upsert:<boolean>
})
🔍 参数说明:
- query:更新查找的条件。
- sort:指定查询得到的文档进行排序。
- update:指定需要删除或更新的字段。
- new:值为 true 时,返回修改后的文档;值为 false 时,返回原始文档。默认值为 false。
- field:要返回的字段子集。
- upsert:此参数的默认值为 false。如果为 true,则当 update 方法中没有文档与给定条件匹配时,它将在集合中创建一个新文档。
下面表格中是原子性操作的常用命令 👇:
| 操作 | 说明 | 示例 |
|---|---|---|
| $set | 用来指定一个键并更新键值,如果这个键不存在就创建这个键。 | {$set:{field:value}} |
| $unset | 用来删除一个键。 | {$unset:{field:1}} |
| $inc | 可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。 | {$inc:{field:value}} |
| $push | 把 value 值追加到 field 里面去,field 一定要是数组类型才行,如果 field 不存在,则会新增一个数组类型加进去。 | {$push:{field:value}} |
| $pushAll | 同 push 一样,只不过 pushAll 一次可以追加多个值到一个数组字段内。 | {$pushAll:{field:value_array}} |
| $pull | 从数组 field 内删除一个等于 value 值。 | {$pull:{field:_value}} |
| $addToSet | 增加一个值到数组内,而且只有当这个值不在数组内才增加。 | {$addToSet:{field:new_value}} |
| $pop | 删除数组的第一个或最后一个元素。传入的值为 -1 删除第一个元素,传入的值为 1 删除最后一个元素。 | {$pop:{field:1}} |
| $rename | 修改字段名称。 | {$rename:{old_field_name:new_field_name}} |
隔离性
我们知道所谓的隔离性(Isolation) 就是一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。而 MongoDB 为多文档隔离性操作提供了 $isolated 操作符。当使用 update 这样的一些更新命令在指定查询条件范围字段上设置 $isolated:1 时,满足条件的文档,在执行 update 命令时具有隔离性。也就是说在执行更新命令期间,其他用户的进程无法对正在执行的相关文档进行读写操作。
✨ 说明:在 MongoDB 4.0 已经开始支持事务了,此时已经没有了$isolated 操作符了。
将集合 q1 中所有文档中 unit 字段的值改为 ¥(原值为元) 。
a. 修改文档信息,操作如下:
> db.q1.update(
{unit:"元",$isolated:1},
{$set:{unit:"¥"}},
{multi:true}
)
✨ 说明:
$isolated不保证多个文档操作的原子性。$isolated保证多个文档操作不会跟其他操作交错。- 注意这里的
$isolated在 MongoDB 4.0 以后不在支持,由于平台上安装的版本是 4.4,这里就不再演示,后面实验我们会给大家简单介绍事务。