MongoDB:不能使用非数字参数自增



我有一个User文档集合,包含几个字段和一个Bets数组。我正在尝试设置一个我将按时间表运行的更新。在User文档中,Balance字段需要增加(Bets[index])。乘数*投注[指数].金额),投注[指数]需要标记为支付和投注是否成功。

我正在尝试更新的用户文档示例。运行更新后,User.bets[1]。isPaidOut应为true, User.bets[1]。didWin应该是true, User。余额应该增加89(也就是说,因为天花板(1.27 * 70)= 89)。

{
"_id": {
"$oid": "63c9ca0217b00eaef7d6237f"
},
"guildId": "1061387401743831121",
"userId": "307884715677974530",
"userName": "Iron Man",
"balance": {
"$numberDouble": "100.0"
},
"lastClaimedAt": {
"$date": {
"$numberLong": "1674168834621"
}
},
"bets": [
{
"sport": "NFL",
"eventWeek": {
"$numberInt": "2"
},
"team": "New York Giants",
"opponentTeam": "Philadelphia Eagles",
"teamId": {
"$numberInt": "19"
},
"opponentTeamId": {
"$numberInt": "21"
},
"eventId": "401438004",
"amount": {
"$numberInt": "20"
},
"multiplier": {
"$numberDouble": "3.85"
},
"isPaidOut": true,
"didWin": false
},
{
"sport": "NFL",
"eventWeek": {
"$numberInt": "2"
},
"team": "Philadelphia Eagles",
"opponentTeam": "New York Giants",
"teamId": {
"$numberInt": "21"
},
"opponentTeamId": {
"$numberInt": "19"
},
"eventId": "401438004",
"amount": {
"$numberInt": "70"
},
"multiplier": {
"$numberDouble": "1.27"
},
"isPaidOut": false
},
{
"sport": "NFL",
"eventWeek": {
"$numberInt": "2"
},
"team": "San Francisco 49ers",
"opponentTeam": "Dallas Cowboys",
"teamId": {
"$numberInt": "25"
},
"opponentTeamId": {
"$numberInt": "6"
},
"eventId": "401438006",
"amount": {
"$numberInt": "200"
},
"multiplier": {
"$numberDouble": "1.49"
},
"isPaidOut": false
}
],
"createdAt": {
"$date": {
"$numberLong": "1674168834633"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1674338378566"
}
},
"__v": {
"$numberInt": "3"
}
}

这是我的更新。当它运行时,我收到这个错误:uncaught promise rejection: write exception: write errors: [Cannot increment with non-numeric argument: {balance: { $ceil: { $mul: [ "bets.$.amount", "bets.$.multiplier" ] } }}]。我以为这可能是因为类型不匹配,但是所有的文档都和上面的一样。

const winnerId = 21;
const eventId = "401438004";
usersCollection.updateMany(
{ 
bets: {
"$elemMatch": {
eventId: eventId,
isPaidOut: false,
teamId: winnerId
}
}
},
{ 
$set: { "bets.$.isPaidOut" : true, "bets.$.didWin": true }, 
$inc: { 
balance: {$ceil: {$mul: {"bets.$.amount": "bets.$.multiplier"} }}
} 
}
);

$ceil是一个聚合操作符,而不是一个更新操作符,因此,如果您使用带有聚合的更新管道

,则只能在更新时使用它。

您必须使用流水线更新。但是,您将不能使用$字段名。下面是使用$map和$reduce的解决方案。

db.collection.updateMany(
bets: {
"$elemMatch": {
eventId: "401438004",isPaidOut: false,teamId: 21
}
},
[
{
"$set": {
"balance": {                         //set the updated balance
$reduce: {
input: "$bets",                  //iterate through the bets array
initialValue: "$balance",        //start with the existing balance
in: {
$add: [
"$$value",
{
$cond: [                  //check the condition
{$and: [
{$eq: ["$$this.eventId","401438004"]},
{$eq: ["$$this.teamId",21]},
{$eq: ["$$this.isPaidOut",false]}
]},
{$ceil: {$multiply: ["$$this.amount","$$this.multiplier"]}},  //if true, perform the arithmetic operation andd add it to existing $$value
0                                                             //if false, add 0
]
}
]
}
}
},
"bets": {                           //set the updated bets array
$map: {                           //iterate through the bets array
input: "$bets",
in: {
$cond: [                      //check the condition
{$and: [
{$eq: ["$$this.eventId","401438004"]},
{$eq: ["$$this.teamId",21]},
{$eq: ["$$this.isPaidOut",false]}
]},
{
"$mergeObjects": [                    //if true, merge the array element with updated fields
"$$this",
{"didWin": true,"isPaidOut": true}
]
},
{
"$mergeObjects": [                    //if false, keep the array element as it is
"$$this"
]
}
]
}
}
}
}
}
])

演示

最新更新