你知道mongoose中的 __v么

简介: mongoose 在添加数据的时候,会默认给你加上一个属性__v,这个属性的全称是__version,顾名思义是版本的意思,作用是给每一个文档加上版本控制,防止并发来修改数据库的数据。

mongoose 在添加数据的时候,会默认给你加上一个属性__v,这个属性的全称是__version,顾名思义是版本的意思,作用是给每一个文档加上版本控制,防止并发来修改数据库的数据。


d2da5228954800a15757e0aa70fe7543.png


mongoose中的并发管理


在mongoose中,我们可以会有以下操作:


a43b120033196e62a271c4cf868c57c6.png


当多个异步函数同时操作数据库时,就可能发生这样的情况,具体的场景往往发生在并发请求中


面对这种情况,mongoose作出以下假设:


  • 当修改一个文档时,如果某些字段已经不再和数据库对应,说明这个字段的数据是脏数据(dirty data),对于脏数据,不应该对数据库产生影响


  • 当修改一个文档时,如果字段和数据库是对应的,则是正常数据,正常数据可以正常的更改数据库


修改普通字段


执行以下代码:


async function  findById(){
 const stu1 = await StuSchema.findById('6187c8599cf04703abb24c20');
 stu1.stuNo = '20210103';
 stu1.name = 'twinkle';
 await stu1.save();
 const stu2 = await StuSchema.findById('6187c8599cf04703abb24c20');
 stu2.age = 20;
 await stu2.save(); 
}
findById();
复制代码

dbe072653bc9a51c45a33e3c0e995857.png


因此,mongoose对于上述场景的处理如下:


3721cb3a0dfb107ced40da527068490b.png


可以看出,对于user2的修改,name和loginId是脏数据,因此不会更新到数据库中,而age是正常数据,对它的更改会应用到数据库


修改数组


然而,mongoose无法准确的判定对数组是否是脏数据,因此,如果遇到数组的修改,mongoose会做出如下处理:


  • 当新增文档时,会自动添加字段__v,用于记录更新版本号,一开始为0
  • 通过模型实例对数组进行修改后,保存时会在内部调用实例的increment函数,将版本号+1
  • 当其他模型实例也更改了数组,保存时会对比版本号,如果不一致,则会引发VersionError


执行以下代码:


async function  findById(){
 const stu1 = await StuSchema.findById('6187c8599cf04703abb24c20');
 const stu2 = await StuSchema.findById('6187c8599cf04703abb24c20');
 stu1.loves = ['code1'];
 await stu1.save();
 stu2.loves = ['game1'];
 await stu2.save();
}
findById();
复制代码

09ce221c9efc1fefd76da22a3b75807f.png


数据库结果


2c1bc577a0ea41550f64166e9b28bb68.png


原理图如下:


160461cace15c4b2132aa46a92daeb2e.png


出现错误是好事,可以提醒开发者:这一次保存的某些数据是脏数据,应该引起重视。开发者可以灵活的根据具体情况作出处理,比如提示用户保存失败,或者重新获取数据然后保存。


由于mongoose仅针对数组进行版本控制,如果要针对所有字段都进行版本控制,需要使用mongoose的插件:mongoose-update-if-current


插件地址:github.com/eoin-obrien…


使用插件后,所有的字段都将受到版本控制,一旦版本不一致,将引发VersionError

相关文章
|
JavaScript NoSQL MongoDB
100 # mongoose 的使用
100 # mongoose 的使用
64 0
|
网络协议 IDE Linux
mongoose使用详细 -- 如何通过mongoose搭建服务器
mongoose使用详细 -- 如何通过mongoose搭建服务器
954 0
|
2月前
|
JavaScript 前端开发
require
【10月更文挑战第24天】
30 5
|
2月前
|
存储 数据库
mongoose
【10月更文挑战第30天】
24 4
|
3月前
|
JavaScript 前端开发 关系型数据库
使用Sequelize8
使用Sequelize8
28 0
|
6月前
|
JavaScript NoSQL 数据库连接
使用Nodejs + express连接数据库mongoose
【6月更文挑战第3天】这篇文章介绍了如何在Express应用中使用Mongoose连接MongoDB数据库。首先,需要创建一个`db.js`文件,然后通过`npm install mongoose`安装Mongoose驱动。接着,在应用中引入MongoDB模块,建立到数据库的连接。创建一个Mongoose schema定义数据模型,如用户信息表。最后,执行数据库操作,包括查询、插入、更新和删除文档,并在完成后关闭数据库连接。文中还提供了相关代码示例。
201 1
|
NoSQL JavaScript 关系型数据库
Mongoose-开篇
Mongoose 概述 • Mongoose和MySQL的Sequelize一样, 都是NodeJS中操作数据库的对象模型工具 • Mongoose使用面向对象的思想对原生的mongoDB命令进行了封装
86 0
|
NoSQL MongoDB
mongoose之bulkWrite
mongoose之bulkWrite
189 0
|
NoSQL MongoDB 数据库
Mongoose
定义schema 数据库中的schema,为数据库对象的集合,schema是mongoose会用到的一种数据模式,可以理解为表结构的定义:每个schema会映射到mongodb中的一个collection。他不具备操作数据库的能力
124 0
Mongoose
|
资源调度 NoSQL 机器人
mongo 进阶之—— mongoose 认识
不管是哪种代码的环境,如果需要连接数据库,都需要使用数据库的驱动。(以下代码的环境是node为例)。在node环境中,mongodb的驱动就叫做mongodb,但是这个驱动也有一个缺陷,模型的验证做的不是很好,一般我们都会使用mongoose 这个库来自定模型,验证参数等
mongo 进阶之—— mongoose 认识