I am trying to update a document from within a transaction. I am using 'findbyidandupdate' with a session object passed in, but I get this error:
MongooseError: Callback must be a function, got [object Object]
Related backend code in Node.js. The session object is created from a data model object, in this case the data object is '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})
}
Looks like the method cannot accept a session object. How do I pass a session object to an update method?
From the Mongoose documentation, findByIdAndUpdate
has a different signature from the one you have used. First of all, findByIdAndUpdate
is just an utility method that eventually calls findOneAndUpdate
, as also pointed out in the documentation, so the arguments are basically the same.
The problem you have is that you are passing too many arguments: since you are using the async
version of the function, you should pass at most 3 arguments. Instead, for the callback version, you need 4 arguments with the callback at the end.
This is how you should have called the findByIdAndUpdate
:
const deviceUpdateResults = await Device.findByIdAndUpdate(
deviceid,
{ $push: { "reviews": reviewid } },
{ session: session, new: true}
);
Few observations not really about your issue:
ClientSession
with startSession
, I expect you also need to close it with endSession
. The alternative (for the native driver) is to use withSession
that accepts a callback where the session is valid.readPreference: 'primary'
can be omitted because the transaction can only happen in the primary. The default readConcern
is local
, so you could omit that too.safe
option deprecated? It is not even listed in the documentation anymore.