Javascript 执行多个MongoDB操作的正确方法

Javascript 执行多个MongoDB操作的正确方法,javascript,node.js,mongodb,express,Javascript,Node.js,Mongodb,Express,如果我需要在几个集合上执行两个或三个不同的操作,有没有比将find/update操作链接在一起更好的方法?例如: db.collection('contactinfos').findOneAndUpdate( { _id: ObjectID(contactID) }, { $set: { sharedWith } } ).then(response => { db.collection('users').update( { _id: { $in: sharedWith.

如果我需要在几个集合上执行两个或三个不同的操作,有没有比将
find/update
操作链接在一起更好的方法?例如:

db.collection('contactinfos').findOneAndUpdate(
  { _id: ObjectID(contactID) },
  { $set: { sharedWith } }
).then(response => {
  db.collection('users').update(
    { _id: { $in: sharedWith.map(id => ObjectID(id)) } },
    { $addToSet: { hasAccessTo: contactID } },
    { multi: true }
  ).then(response => {
    db.collection('users').update(
      { _id: { $in: notSharedWith.map(id => ObjectID(id)) } },
      { $pull: { hasAccessTo: contactID } },
      { multi: true }
    ).then(response => {
      return res.send({ success: true });
    }).catch(err => {
      logger.error(`in updating sharing permissions for ${contactID} by user ${_id}`, err);
      return res.status(400).send({ reason: 'unknown' });
    });
  }).catch(err => {
    logger.error(`in updating sharing permissions for ${contactID} by user ${_id}`, err);
    return res.status(400).send({ reason: 'unknown' });
  });
}).catch(err => {
  logger.error(`in updating sharing permissions for ${contactID} by user ${_id}`, err);
  return res.status(400).send({ reason: 'unknown' });
});
这看起来很混乱,必须有更好的方法。此外,如果在第一个
findOneAndUpdate
之后出现错误,阻止其他
update
运行,则文档中的数据将不一致。这些文档包含对其他文档的ID引用,以便更快地查找


还有,有没有一种方法可以捕获承诺链中的所有错误?

从您的回调地狱中,我可以看到您在任何地方都没有使用
.then()
方法的
response
参数。如果不需要一个查询的结果来执行另一个查询,请考虑使用方法:

Promise.all()
将继续执行以下
。然后()
仅当所有承诺都已解决时,否则它将落入
.catch()
方法。对于错误处理,您可以轻松地链接多个
.catch()
方法,这一点已经很好地解释过了

如果您不能有任何数据不一致,请执行以下任一操作:

  • 使用事务获取一些SQL数据库(更简单的解决方案)
  • 调查
  • 如果这是可以接受的,比如说每1kk次一次,一定要在你的应用程序逻辑中检查它的一致性

    const updateContactInfo = db.collection('contactinfos')
        .findOneAndUpdate(
            { _id: ObjectID(contactID) }, 
            { $set: { sharedWith } }
        );
    const updateUsers = db.collection('users')
        .update(
            { _id: { $in: sharedWith.map(id => ObjectID(id)) } }, //hint: use .map(ObjectId) instead.
            { $addToSet: { hasAccessTo: contactID } },
            { multi: true }
        );
    const updateUsers2 = db.collection('users')
        .update(
            { _id: { $in: notSharedWith.map(id => ObjectID(id)) } }, //hint: use .map(ObjectId) instead.
            { $pull: { hasAccessTo: contactID } },
            { multi: true }
        );
    
    Promise
        .all([updateContactInfo, updateUsers, updateUsers2])
        .then((values) => {
    
            const updateContactInfoResult = values[0];
            const updateUsersResult       = values[1];
            const updateUsers2Result      = values[2];
    
            return res.send({ success: true });
    
        })
        .catch((reason) => {
    
            logger.error(`msg`, reason);
            return res.status(400).send({ reason: 'unknown' });
    
        });