Mongodb 事务内更新

Mongodb updates within a transaction

我正在尝试从事务中更新文档。我正在使用 'findbyidandupdate' 和传入的会话对象,但出现此错误:

MongooseError: Callback must be a function, got [object Object]

Node.js中的相关后端代码。会话对象是从数据模型对象创建的,在本例中数据对象是 'Device':

const session = await Device.startSession();

const transactionOptions = {
        readPreference: 'primary',
        readConcern: { level: 'local' },
        writeConcern: { w: 'majority' }
    };

const transactionResults = await session.withTransaction( async () => {
               const deviceUpdateResults = await 
    Device.findByIdAndUpdate(
                {session},
                (deviceid),
                {$push: {"reviews": (reviewid)}},
                { new : true, safe: true})
}

看起来该方法无法接受会话对象。如何将会话对象传递给更新方法?

来自 Mongoose 文档,findByIdAndUpdate has a different signature from the one you have used. First of all, findByIdAndUpdate is just an utility method that eventually calls findOneAndUpdate,正如文档中指出的那样,因此参数基本相同。

您遇到的问题是传递的参数太多:由于您使用的是函数的 async 版本,因此最多应传递 3 个参数。相反,对于回调版本,您需要 4 个参数,最后是回调。

你应该这样调用 findByIdAndUpdate:

const deviceUpdateResults = await Device.findByIdAndUpdate(
    deviceid,
    { $push: { "reviews": reviewid } },
    { session: session, new: true}
);

很少有与您的问题无关的观察:

  • 我一直使用 MongoDB 的 NodeJS 本机驱动程序,所以我对 Mongoose 很陌生,但是如果你用 startSession 启动 ClientSession,我希望你也需要用 endSession 关闭它。另一种方法(对于本机驱动程序)是使用 withSession 在会话有效的情况下接受回调。
  • 至于现在,readPreference: 'primary' 可以省略,因为事务只能发生在主节点上。默认的 readConcernlocal,所以你也可以省略它。
  • safe 选项是否已弃用?它甚至不再在文档中列出。

您为什么不尝试使您的代码更简单一些。 试试这个

await Device.updateOne({_id:_id},{$push:{"reviews":reviewId});

其中第一个参数过滤数据,第二个参数更新数据