我有一个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"
]
}
]
}
}
}
}
}
])
演示