0

I'm trying to update some of the value inside nested arrays using id as shown below:-

Nested array:-

let people = [
    {
        "_id": 1,
        "name": "Person 1",
        "pets": [
            {
                "_id": 1,
                "name": "Tom",
                "category": "cat",
                "favFood": [
                    {
                        "_id": 1,
                        "name": "steamed fish", // this will be updated
                        "gred": "A" // this will be updated
                    },
                    {
                        "_id": 2, 
                        "name": "fried fish",
                        "gred": "B"
                    }
                ]
            },
            {
                "_id": 2,
                "name": "Jerry",
                "category": "mouse",
                "favFood": [
                    {
                        "_id": 1,
                        "name": "cheese",
                        "gred": "C"
                    }
                ] 
            }
        ]
    }
]

Right now I've something like this:-

People.updateOne(
    { "$set": { "pets.$[petID].favFood.$[favFoodID].name" : "bbq fish", 
                "pets.$[petID].favFood.$[favFoodID].gred" : "A+" }             
    },
    {
      multi: true,
      arrayFilters: [ 
          { "petID._id": 1 }, // pet with id of '1'
          { "favFoodID._id": 1 } // favFood with id of '1'
        ]
    },
    (err, success) => {
        if(err) res.json({ message: `Unsuccessful!`, report: err })
        else res.json({ message: `Successful!`, report: success })
    }
)

But, unfortunately I got error of "message": "\"_id\" is not allowed". And I don't know which _id that was not allowed or cause of the error.

What I would want is to alter or update as following:-

let people = [
    {
        "_id": 1,
        "name": "Person 1",
        "pets": [
            {
                "_id": 1,
                "name": "Tom",
                "category": "cat",
                "favFood": [
                    {
                        "_id": 1,
                        "name": "bbq fish", // this value was updated
                        "gred": "A+" // this value was updated
                    },
                    {
                        "_id": 2, 
                        "name": "fried fish",
                        "gred": "B"
                    }
                ]
            },
            {
                "_id": 2,
                "name": "Jerry",
                "category": "mouse",
                "favFood": [
                    {
                        "_id": 1,
                        "name": "cheese",
                        "gred": "C"
                    }
                ] 
            }
        ]
    }
]

Can anyone direct me on which part on my codes above causing the error?

Adjusted updateOne:-

People.updateOne(
    { "_id": 1,
      "pets._id": 1,
      "favFood._id": 1 
    },
    { $set: { "pets.favFood.$$.name" : "bbq fish", 
              "pets.favFood.$$.gred" : "A+", } 
    },
    (err, success) => {
        if(err) res.json({ message: `Unsuccessful!`, report: err })
        else res.json({ message: `Successful!`, report: success })
    }
)

It's able to return Successful!. But the values in database does not change. From here, how can I tweak my code?

lala
  • 1,309
  • 9
  • 21
  • Which version of mongodb are you using? – thammada.ts Jul 15 '20 at 07:25
  • The use of `multi: true` doesn't belong in the `collection#updateOne` method. – prasad_ Jul 15 '20 at 07:39
  • @thammada.ts I'm using Mongoose with Nodejs. Version of Mongoose is `5.9.20` – lala Jul 15 '20 at 08:33
  • @prasad_ then should not use `multi:true`? Cause it still returns the same error. – lala Jul 15 '20 at 08:37
  • 2
    The syntax is still not correct. The `updateOne`'s first parameter must be a _query.filter_; your code doesn't have any. Please follow the syntax from the following link: [updateOne](https://mongoosejs.com/docs/api.html#model_Model.updateOne) method of Mongoose. – prasad_ Jul 15 '20 at 09:03
  • @prasad_ I've adjusted the code as what being implemented here at this [link](https://www.nodechef.com/docs/cloud-search/updates-documents-nested-in-arrays). Please refer above. – lala Jul 15 '20 at 09:46
  • The query filter is not correct. The _field path_ to the `"favFood._id": 1` is not correct. – prasad_ Jul 15 '20 at 09:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/217890/discussion-between-lala-and-prasad). – lala Jul 15 '20 at 09:59
  • This should solve: [How to use arrayFIlters with Mongoose](https://stackoverflow.com/questions/49095532/how-yo-use-arrayfilters-with-mongoose-5-x-x) – prasad_ Jul 15 '20 at 10:14

1 Answers1

0

Here is the answer:-

Working Code for updateOne:-

People.updateOne(
    {},
    { "$set": { "pets.$[petID].favFood.$[favFoodID].name" : "bbq fish", 
                "pets.$[petID].favFood.$[favFoodID].gred" : "A+" 
              } 
    },
    {
      arrayFilters: [ 
          { "petID._id": 1 },
          { "favFood._id": 1 }
        ]
    },
    (err, success) => {
        if(err) res.json({ message: `Unsuccessful!`, report: err })
        else res.json({ message: `Successful!`, report: success })
    }
)
lala
  • 1,309
  • 9
  • 21