If I have a document like this:
db.people.insertOne({name: "Annie", latestScore: 5});
Then based on this answer, I am able to move latestScore
to an array field like this:
db.people.updateOne(
{name: 'Annie'},
[
{$set:
{scoreHistory:
{$concatArrays: [
{$ifNull: ["$scoreHistory", []]},
["$latestScore"]
]}
}
},
{ $unset: ["latestScore"] }
]
);
This is the resulting document:
{
_id: ObjectId("61d2737611e48e0d0c30b35b"),
name: 'Annie',
scoreHistory: [ 5 ]
}
Can we perform the same update to objects nested in an array? For example, if the document is like this:
db.people.insertOne({
name: 'Annie',
words: [
{word: "bunny", score: 5},
{word: "pink", score: 5}
]
});
How can we update it to this:
{
name: 'Annie',
words: [
{word: "bunny", scoreHistory: [5]},
{word: "pink", scoreHistory: [5]}
]
}
I know I can iterate and modify the array from the app and update the whole array at once, but I would like to do it using operators like in the first example above.
The website first displays words.word
and words.score
in rows, clicking on a row shows words.scoreHistory
in a popup. I am expecting words array to be less than 500. Any advise on remodelling the schema to simplify the above operation is also welcome!
CodePudding user response:
db.collection.update({
name: "Annie"
},
[
{
$set: {
words: {
$map: {
input: "$words",
as: "m",
in: {
word: "$$m.word",
scoreHistory: {
$concatArrays: [
{
$ifNull: [
"$$m.scoreHistory",
[]
]
},
[
"$$m.score"
]
]
}
}
}
}
}
}
])