Reputation: 3051
I am making a voting system in which an object will have an array called scores
, every time it is qualified a record will be entered to this array as long as the same id does not exist.
Sample Doc :
{
name:"jose luis",
scores:[]
}
The user push :
{id:1,stars:5}
Updated Doc :
{
name:"jose luis",
scores:[{id:1,stars:5}]
}
The user push 2nd time :
{id:1,stars:4}
Updated Doc :
{
name:"jose luis",
scores:[{id:1,stars:4}]
} //this should update the value of the stars under the array element with the existing id.
I have tried this :
Politico.update(
{ name: "jose luis" },
{
$setOnInsert: { "$scores.id": body.req.id},
"$addToSet": {
scores: {
"id": body.req.id,
"starts": body.req.stars
}
}
},
{ upsert: true }
I have tried this but it doesn't work, how can I fix it? Thanks a lot.
Upvotes: 1
Views: 494
Reputation: 17915
On MongoDB 4.2
or above as you can use aggregation-pipeline in updates, try below query :
Politico.updateOne(
{ name: "jose luis" },
[{
$addFields: {
scores: {
$reduce: {
input: "$scores",
initialValue: [{ id: 1, stars: 5 }], // Input
in: {
$cond: [
{ $in: ["$$this.id", "$$value.id"] }, /** Check id exists in 'scores' array */
"$$value", /** If YES, return input */
{ $concatArrays: ["$$value", ["$$this"]] }/** If NO, concat value(holding array) with current object as array */
]
}
}
}
}
}]);
You might not need { upsert: true }
as you're not writing a new document with name : "jose Luis"
& respective scores
array. But if you wanted to do that :
Politico.updateOne(
{ name: "jose luis" },
[{
$addFields: {
scores: {
$reduce: {
input: "$scores",
initialValue: [{ id: 1, stars: 5 }], // Input
in: {
$cond: [
{ $in: ["$$this.id", "$$value.id"] }, /** Check id exists in 'scores' array */
"$$value", /** If YES, return input */
{ $concatArrays: ["$$value", ["$$this"]] }/** If NO, concat value(holding array) with current object as array */
]
}
}
}
}
},
{$addFields : {scores : { $ifNull: [ "$scores", {id : 13, stars: 3} ] }}} /** This additional 'addFields' will add 'scores' array with input object to newly created doc */
],{upsert : true});
Test : MongoDB-Playground
Upvotes: 1