Home > database >  MongoDB push existing field value to another field in an array of objects
MongoDB push existing field value to another field in an array of objects

Time:01-03

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"
                ]
              ]
            }
          }
        }
      }
    }
  }
])

mongoplayground

  • Related