简体   繁体   English

mongoose documentation.save() 方法不明确

[英]Unclarity in mongoose documentation .save() method

In the mongoose docs, it is clearly written that the.save() method is the best one to store data on mongoDB because it has validators and middlewares.在 mongoose 文档中,清楚地写道 .save() 方法是在 mongoDB 上存储数据的最佳方法,因为它具有验证器和中间件。 This is what is written:这是这样写的:

Note that update(), updateMany(), findOneAndUpdate(), etc. do not execute save() middleware.注意update()、updateMany()、findOneAndUpdate()等不执行save()中间件。 If you need save middleware and full validation, first query for the document and then save() it.如果您需要保存中间件和完整验证,请先查询文档,然后保存()它。

Therefore I wanted to use it.因此我想使用它。 But I faced problems:但是我遇到了问题:

  • Query, modify and then save the doc could make my code fail because of asynchronicity.查询、修改然后保存文档可能会使我的代码由于异步而失败。 (during the time of modify, the doc is still stored as unmodified on the DB, so if 2 modifcation happened at once, one could be erased) (在修改过程中,文档仍然以未修改的形式存储在数据库中,因此如果同时发生 2 次修改,则可以删除其中的一次)

  • I'm using eslint and modifying the object creates a no-param-reassign error: https://eslint.org/docs/latest/rules/no-param-reassign .我正在使用 eslint 并修改 object 创建 no-param-reassign 错误: https://eslint.org/docs/latest/rules/no-param-reassign

async function request(userId) {
  const userToUpdate = await UserModel.findOne({ _id: userId });
  //There is time here to receive a new request that will bypass this one
  userToUpdate.value = "xxx"; 
  // The line above throws a no-param-reassign eslint error
  UserModel.save(userToUpdate);
}

Using spread operator to deconstruct doesn't work.使用扩展运算符解构不起作用。

async function request(userId) {
  const userToUpdate = await UserModel.findOne({ _id: userId });
  //There is still time here to receive a new request that will bypass this one
  UserModel({ value: "xxx", ...userToUpdate.toObject() }).save();
}

throws =>抛出 =>

MongoServerError: E11000 duplicate key error collection: test.users index: _id_ dup key:

and I understand this error, it doesn't recognize the { value: "xxx", ...userToUpdate.toObject() } as the same object and think i am trying to overwrite我理解这个错误,它无法将 { value: "xxx", ...userToUpdate.toObject() } 识别为相同的 object 并认为我正在尝试覆盖

Anyway, I'm using updateOne for the moment, do you think you could help to make.save() work or should I stick to updateOne?无论如何,我目前正在使用 updateOne,你认为你可以帮助 make.save() 工作还是我应该坚持使用 updateOne?

It's not UserModel.save(userToUpdate);这不是UserModel.save(userToUpdate); it's userToUpdate.save();它是userToUpdate.save();

Regarding the concurrent updates - mongoose uses revision control to address this issue.关于并发更新 - mongoose 使用版本控制来解决此问题。 Try it:试试看:

const user1 = await UserModel.findOne({ _id: userId });
const user2 = await UserModel.findOne({ _id: userId }); // <-- same userId 
user1.value = "xxx"; 
await user1.save();
user2.value = "yyy"; 
await user2.save(); // <-- throws VersionControll exception

Docs: https://mongoosejs.com/docs/api/error.html#error_Error-VersionError文档: https://mongoosejs.com/docs/api/error.html#error_Error-VersionError

It's one of fundamental architectural decisions behind Mongoose.这是 ZCCADCDEDB567ABAE643E15DCF0974E503Z 背后的基本架构决策之一。 If you don't like how they handle permissions, discrimination, or population it would be advisable to do not use the ODM - you will end up fighting it instead of using it.如果您不喜欢他们处理权限、歧视或人口的方式,建议您不要使用 ODM - 您最终会与它抗争而不是使用它。 It was not designed one-size-fits-all, but rather focused to simplify specific usecases.它的设计不是万能的,而是专注于简化特定的用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM