Mongodb обновляет транзакцию

avatar
sotn
9 августа 2021 в 02:23
241
2
-2

Я пытаюсь обновить документ из транзакции. Я использую findbyidandupdate с переданным объектом сеанса, но получаю следующую ошибку:

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

Связанный внутренний код в Node.js. Объект сеанса создается из объекта модели данных, в данном случае объектом данных является «Устройство»:

.
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})
}

Похоже, метод не может принять объект сеанса. Как передать объект сеанса методу обновления?

Источник
turivishal
12 августа 2021 в 06:29
0

не могли бы вы обновить свой вопрос, указав более подробную информацию: 1) опубликовать проверенный запрос 2) что такое объект сеанса, показать, что в нем находится 3) утешить ваш ввод 4) показать ожидаемый результат.

Ответы (2)

avatar
Marco Luzzara
14 августа 2021 в 21:25
2

Из документации Mongoose, findByIdAndUpdate имеет подпись, отличную от той, которую вы использовали. Прежде всего, findByIdAndUpdate — это просто служебный метод, который в конечном итоге вызывает findOneAndUpdate, как также указано в документации, поэтому аргументы в основном те же.

Ваша проблема заключается в том, что вы передаете слишком много аргументов: поскольку вы используете версию функции async, вы должны передать не более 3 аргументов. Вместо этого для версии с обратным вызовом вам нужны 4 аргумента с обратным вызовом в конце.

Вот как вы должны были назвать findByIdAndUpdate:

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

Несколько замечаний, не совсем относящихся к вашей проблеме:

  • Я всегда использовал родной драйвер NodeJS для MongoDB, поэтому Mongoose мне почти неизвестен, но если вы начинаете ClientSession с startSession, я полагаю, вам также нужно закрыть его с endSession. Альтернативой (для собственного драйвера) является использование withSession, который принимает обратный вызов, если сеанс действителен.
  • На данный момент readPreference: 'primary' можно опустить, поскольку транзакция может произойти только в первичном. По умолчанию readConcern равно local, так что его тоже можно опустить.
  • Разве опция safe не устарела? Его даже больше нет в документации.
avatar
Muhammad Mujtaba Shafique
17 августа 2021 в 20:43
0

Почему бы вам не сделать свой код немного проще. Попробуйте это

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

Где первый параметр фильтрует данные, а второй обновляет данные