-2

I would like to update a single value in a mongo document that is an array of arrays of arrays,

Here is the code that I have thus far... but it's not working. I think I need to use the $ operator on the chart to access the currently selected chorePerson... but not sure how that works.

I am really struggling with the mongoDB syntax and updating arrays

This is my data set, I have put in a t1, t2 and t3 in each of the respective arrays...

[
  {
    "_id": "5e3d891d956bb31c307d8146",
    "t1": 0,
    "affiliation": "800_800",
    "year": 2020,
    "month": "February",
    "weekNumber": 6,
    "weekStart": "02/02/2020",
    "weekEnd": "02/08/2020",
    "chart": [
      {
        "t2": 0,
        "_id": "5e3d8a6358a3d92448e85aa5",
        "ordinal": 5,
        "ordinalString": "Friday",
        "chorePerson": [
          {
            "completed": false,
            "t3": 0,
            "_id": "5e3d8a6358a3d92448e85aa7",
            "person": "Frank",
            "personID": "5e2891587678601434f6929c",
            "phone": "8008008002",
            "chore": "Another one",
            "choreID": "5e39ca3949acee16fc280c98"
          }
        ]
      }
    ],
    "date": "2020-02-07T16:03:47.770Z",
    "__v": 0
  }
]

I have been able to update t1 and t2 using this query:

{"_id":"5e3d891d956bb31c307d8146","chart._id":"5e3d9260fc365c2d080a32ce"}

and a set call of

{"$set":{"t1":1,"chart.$.t2":2}}

but I cannot figure out how to go down one more level in the arrays

Here is my query: I have hard coded the 'chart[ 1 ]' to try to force it to fetch only that record

{"_id":"5e3d891d956bb31c307d8146","chart._id":"5e3d8a6358a3d92448e85aa5","chart[1].chorePerson._id":"5e3d8a6358a3d92448e85aa7"}

This is my 'set' call

{"$set":{"t1":1,"chart.$.t2":2,"chart.$[].chorePerson.$.t3":3}}

When I run this in my program I get:

error Updating the path 'chart.$[].chorePerson.$.t3' would create a conflict at 'chart'

UPDATE 1

So I tried this:

{"_id":"5e3d93777f099b28b0fff2ae","chart._id":"5e3d953ed92a082738e8e2b9","chart.chorePerson._id":"5e3d953ed92a082738e8e2bb"}

{"$set":{"t1":1,"chart.$.t2":2,"chart.$.chorePerson.$.t3":3}}

which gave me:

error Too many positional (i.e. '$') elements found in path 'chart.$.chorePerson.$.t3

So I thought I would go back to the answer posted by whoami:

{"$set":{"t1":1,"chart.$.t2":2,"chart.$[].chorePerson.$.t3":3}}

Which gave me:

error Updating the path 'chart.$[].chorePerson.$.t3' would create a conflict at 'chart'

UPDATE 2

So I tried moving the [] in my set statement to the chart.$.chorePerson

{"$set":{"t1":1,"chart.$.t2":2,"chart.$.chorePerson.$[].t3":3}}

and selecting only the relevant chorePerson (5e3da771e08e3e31ac420004)

{"_id":"5e3da771e08e3e31ac41fffd","chart._id":"5e3da771e08e3e31ac420002","chart.chorePerson._id":"5e3da771e08e3e31ac420004"}

Which is getting me closer... now the data is being set in the correct chore chart and chart, but ALL of the chorePerson fields are being updated even though my select is supposed to only return the chore person '5e3da771e08e3e31ac420004'

enter image description here

MLissCetrus
  • 423
  • 3
  • 21
  • https://stackoverflow.com/users/7237613/whoami - I appreciate your help on this... I have updated the question with ID information – MLissCetrus Feb 06 '20 at 18:43

1 Answers1

0

After trial and error and lots of stack overflow articles, I have finally found the code that does what I need it to do:

                var query = {"chart.chorePerson._id":idCP};

                var update = {$set: {"chart.$.chorePerson.$[elem].completed":true, "chart.$.chorePerson.$[elem].completed_at": Date.now()}};

                var options = {new: true, arrayFilters: [ { "elem._id": { $eq: idCP } } ]};

                if(debugThis){
                    console.log("query " + JSON.stringify(query));

                    console.log("update " + JSON.stringify(update));

                    console.log("options " + JSON.stringify(options));
                }

                // see stackoverflow question:
                // https://stackoverflow.com/questions/60099719/is-this-the-correct-use-of-the-operator-for-findoneandupdate/60120688#60120688

                ChoreChart.findOneAndUpdate( query, update, options)
                    .then(chart => {

                        if(debugThis){
                            console.log('updated chart ' + JSON.stringify(chart));
                        }

                        return resolve(msgResponse);
                })
                .catch(err => {
                    msgResponse.message('error ' + err.message);
                    return resolve(msgResponse);
                })

Which yields exactly what I want:

enter image description here

Many thanks to the people who wrote these articles:

https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/#behavior

Update nested subdocuments in MongoDB with arrayFilters

Updating a Nested Array with MongoDB

How to Update Multiple Array Elements in mongodb

arrayFilters in mongodb

https://github.com/Automattic/mongoose/issues/6386

MLissCetrus
  • 423
  • 3
  • 21