Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose update a field in an object of array

I'm using mongoose findOneAndUpdate() In mongodb i have a database with objects inside an array look like this:

patients model

{
        "_id" : ObjectId("5cb939a3ba1d7d693846136c"),
        "myArray" : [
            {
                "name" : "PW6178281935-20190425",
                "treatment" : "beauty",
                "value" : 0 <- i want to update this
            },
            {
                "name" : "PW6178281935-24142444",
                "treatment" : "muscle",
                "value" : 0
            }
        ] 
},
 {
        "_id" : ObjectId("5cc123a3bb2d3123a932475f"),
        "myArray" : [
            {
                "name" : "PW6178281935-43535555",
                "treatment" : "helps",
                "value" : 0 
            },
            {
                "name" : "PW6178281935-92732978",
                "treatment" : "documents",
                "value" : 0
            }
        ] 
}

i want to update value of an object with treatment = "beauty" of _id = "5cb939a3ba1d7d693846136c"

in schema "value" has default value of 0

i had tried with this but the value doesn't get update

patients.findOneAndUpdate({$and:[{'patients._id' : 5cb939a3ba1d7d693846136c}, {'myArray.treatment' : beauty}]}, { $set: { 'myArray.$.value': 424214 } }, { new: true });

Am I doing something wrong?

EDIT:

The answer from Frank Rose was right , the reason arrayFilters doesn't work for me because the project i was working on using mongoose 4.4 which doesn't support arrayFilters of mongoDB yet.If you want to use arrayFilters with your project please use mongoose version 5 or later.After i upgrade to mongoose 5.5 i was able to edit the object

like image 674
Linh Nguyen Avatar asked Dec 03 '22 10:12

Linh Nguyen


1 Answers

The reason why your query isn't working as expected is because you are not actually targeting the specific array element you want to update.

Here's how I would write the query:

 patients.findOneAndUpdate(
  {_id: "5cb939a3ba1d7d693846136c"},
  {$set: {"myArray.$[el].value": 424214 } },
  { 
    arrayFilters: [{ "el.treatment": "beauty" }],
    new: true
  }
)

To break down what's happening:

1) First we're looking for the patient by ID

2) Then using $set we specify which updates are being applied. notice the $[el] syntax. this is referring to an individual element in the array. you can name it what ever you want but it must match the variable name used in arrayFilters.

3) Then in the configuration object we specify arrayFilters which is saying to only target array elements with "treatment" equal to "beauty"

Note though that it will target and update all array elements with treatment equal to "beauty". If you haven't already you'll want to ensure that the treatment value is unique. $addToSet could be useful here, and would be used when adding elements to the array.

like image 146
Frank Rose Avatar answered Dec 24 '22 05:12

Frank Rose