На MongoDB 4.2
или выше, так как вы можете использовать агрегационный конвейер в обновлениях, попробуйте следующий запрос:
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 */
]
}
}
}
}
}]);
Возможно, вам не нужно { upsert: true }
, поскольку вы не пишу новый документ с name : "jose Luis"
и соответствующим scores
массивом. Но если вы хотите сделать это:
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});
Тест: MongoDB-Playground