0

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!

1 Answer 1

2
db.collection.update({
  name: "Annie"
},
[
  {
    $set: {
      words: {
        $map: {
          input: "$words",
          as: "m",
          in: {
            word: "$$m.word",
            scoreHistory: {
              $concatArrays: [
                {
                  $ifNull: [
                    "$$m.scoreHistory",
                    []
                  ]
                },
                [
                  "$$m.score"
                ]
              ]
            }
          }
        }
      }
    }
  }
])

mongoplayground

Sign up to request clarification or add additional context in comments.

2 Comments

This query overrides history on every update; a modification was required to make the scoreHistory field actually behave like a history by preserving values - mongoplayground - preserve history. SO is not allowing me to suggest this as an edit as the edit queue is full.
@AndrewNessin I update my answer with your suggest

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.