0

I have a collection of users that has an array of multiple plates :

users : [
{
_id: '61234XXX'
plates: [
 {
   _id: '123'
   'color': 'orange'
 },
 {
   _id: '124'
   'color': 'blue'
 }
]
},
{
_id: '63456XXX'
plates: [
 {
   _id: '321'
   'color': 'orange'
 },
 {
   _id: '432'
   'color': 'green'
 }
]
}
]

I'm trying to figure out a way to add a new field to the all current plate objects for every user:

I've got to this:

  await User.findOneAndUpdate(
      { _id: '63456XXX' },
      {
        $set : {
          [`plates.0.plateStyle`]: "testValue"
        }
      }
  )

Tho this works it's not fit for purpose. Is there a better way I can iterate over this?

1 Answer 1

1

You can try this query:

Here you are using array filters to tell mongo: "Where you find an object with _id: "61234XXX" and exists the plates then, there, get the document (elem) which match that plates is not empty (to get all) and add plateStyle".

await User.updateMany({
  _id: "61234XXX",
  plates: {
    $exists: true
  }
},
{
  $set: {
    "plates.$[elem].plateStyle": "testValue"
  }
},
{
  arrayFilters: [
    {
      elem: { $ne: [ "$plates", [] ] }
    }
  ]
})

Example here

Also if you are finding by _id you won't need updateMany since _id is unique and only will be 1 or 0 results.

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

4 Comments

Hey! Thanks for taking the time! unfortunately that doesn't work, the example you shared only shows it updating the first object in the array
Sorry, my mistake, the trick is to use array filters.
Thanks! If you could, could you explain whats happening here? { elem: { $ne: [ "$_id", null ] } the $ne onwards has thrown me off and can't find its ref in the docs
$ne is "not equal". Here is used to match all documents which _id is not equal to null. Also in the link I've used $ne: ["$plates",[]] which I think is better. This is to match all elements where exists the array plates. What is basically you want, if exists the array, update the element.

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.