Начиная с MongoDB 4.2, вы можете использовать конвейер агрегации для операций обновления.
https://docs.mongodb.com/manual/tutorial/update-documents-with-aggregation-pipeline/
Это означает, что вы можете обновлять документ, в то время как вы также можете проверить значение текущего документа. Но конвейер агрегации для операции обновления не поддерживает оператор $inc
, поэтому вам придется немного изменить обновление. В вашем случае это будет:
db.profiles.update(
{ _id: transaction.receiver },
[{
$set: {
balance: {
$cond: [
{ $lte: ['$balance', -decimal(transaction.amount)] }, // balance + amount <= 0
0,
{ $add: ['$balance', decimal(transaction.amount)] }
]
}
}
}]
)
Если вы используете более раннюю версию MongoDB, вы можете разделить запрос на обновление на 2 операции, используя баланс как часть вашего условия
db.profiles.update(
{ _id: transaction.receiver, balance: { $lte: -decimal(transaction.amount) } },
{ $set: { balance: 0 } }
)
db.profiles.update(
{ _id: transaction.receiver, balance: { $gt: -decimal(transaction.amount) } },
{ $inc: { balance: decimal(transaction.amount) } }
)