mongoDB同时更新2个集合

时间:2017-11-25 01:06:06

标签: node.js mongodb express mongoose

我正在寻找同时更新2个馆藏的不同方法,在下列情况下,我更新了医生案例的数量

我的Mongo DB文档结构:

医生收集:

 { 
    "_id" : ObjectId("5a18a637346826574416a588"), 
    "doc_fname" : "Bob", 
    "doc_lname" : "Smith", 
    "numOfCases" : NumberInt(6), 
    "__v" : NumberInt(0)
 }

CustomerCases Collection:

{ 
    "_id" : ObjectId("5a18c02221344b58585105ea"), 
    "doctor_id" : ObjectId("5a18a637346826574416a588"), 
    "cust_fname" : "test", 
    "cust_lname" : "test", 
    "case_type" : "Crowns", 
    "__v" : NumberInt(0)
}

NodeJS Mongoose代码:

var NewCustomerCase = req.body;


CustomerCases.create(NewCustomerCase, function(err,CustomerCase){
    if(err){
        throw err;
    }
    else{
        var query = {_id:NewCustomerCase.doctor_id};
        // if the field doesnt exsit $set will set q new field
        var update = {
            '$inc': {'numOfCases': 1}
        }
        // when true return the updated document
        var options = {new:true};
        Doctors.findOneAndUpdate(query,update,options,function(err,updatedDocter){
            if(err){
                throw err;
            }
        });
        res.json(CustomerCase);
    }

});

这种方法工作正常,有没有更好的方法来解决这个问题,据我所知,它不可能同时执行2个收集

2 个答案:

答案 0 :(得分:0)

这些是我的想法: -

  1. 使用promises而不是回调。

  2. 使用promise.all连接您的请求并同时执行它们。

答案 1 :(得分:0)

如果您要更新的文档并不相互依赖,则可以同时更新它们。例如,通过制作两个承诺,然后使用Promise.all()

同时运行它们
const customerPromise = CustomerCases.create(NewCustomerCase);
const doctorPromise = Doctors.findOneAndUpdate(query, update, options);

Promise.all([customerPromise, doctorPromise])
  .then((result) => {
    return res.status(200).json(result);
  }).catch((err) => {
    return res.status(400).json(err);
  });

当客户和医生承诺得到解决时,Promise.all()返回的承诺将得到解决。文档为here

如果出现错误,则会出现此问题。如果客户未能更新,医生仍然会将numOfCases增加1.如果医生文档未能更新,则仍会提供客户案例。事实上,你确实在文档之间存在一些依赖关系,而Promise.all()可能并不是一个好的解决方案。这通常是交易发挥作用的地方,但MongoDB中的交易超出了这个答案的范围,所以我只是发布这个link

您已经使用回调顺序运行数据库操作。基于async/await

,这是一种更现代的方式
try {
  const newCustomerCaseFromDb = await CustomerCases.create(NewCustomerCase);
  const doctorUpdated = await Doctors.findOneAndUpdate(query, update, options);
  return res.status(200).json({ newCustomerCaseFromDb, doctorUpdated });
} catch(err) {
  return res.status(400).json(err);
}

使用await的功能需要async关键字。

首先创建客户案例。如果失败,它会跳进catch块。如果成功,则继续寻找并更新医生。使用await使其看起来像同步代码。