JackieWillen
JackieWillen

Reputation: 749

How to update a field of an object in array of array in MongoDB?

My mongodb data is like this,a little complicated because of array in array.

{
"_id" : ObjectId("5e36950f65fae21293937594"),
"userId" : "5e33ee0b4a3895a6d246f3ee",
"notes" : [ 
    {
        "noteId" : ObjectId("5e36953665fae212939375a0"),
        "time" : ISODate("2020-02-02T17:24:06.460Z"),
        "memoryLine" : [ 
            {
                "_id" : ObjectId("5e36953665fae212939375ab"),
                "memoryTime" : ISODate("2020-02-03T17:54:06.460Z"),
                "hasReviewed": false
            }, 
            {
                "_id" : ObjectId("5e36953665fae212939375aa"),
                "memoryTime" : ISODate("2020-02-03T05:24:06.460Z"),
                "hasReviewed": false
            }
        ]
    }
]}

I want to update hasReviewed in memoryLine with _id.For example, i want to update _id:ObjectId(5e36953665fae212939375ab) item's hasReviewed to true . As expected like below :

{
"_id" : ObjectId("5e36950f65fae21293937594"),
"userId" : "5e33ee0b4a3895a6d246f3ee",
"notes" : [ 
    {
        "noteId" : ObjectId("5e36953665fae212939375a0"),
        "time" : ISODate("2020-02-02T17:24:06.460Z"),
        "memoryLine" : [ 
            {
                "_id" : ObjectId("5e36953665fae212939375ab"),
                "memoryTime" : ISODate("2020-02-03T17:54:06.460Z"),
                "hasReviewed": true    <============here updated to true
            }, 
            {
                "_id" : ObjectId("5e36953665fae212939375aa"),
                "memoryTime" : ISODate("2020-02-03T05:24:06.460Z"),
                "hasReviewed": false
            }
        ]
    }
]}

How to deal with it?Thank you.

Upvotes: 0

Views: 51

Answers (2)

JackieWillen
JackieWillen

Reputation: 749

I find a solution for this.

db.notes.updateOne({
    userId:"5e33ee0b4a3895a6d246f3ee",
    'notes.0.memoryLine._id': ObjectId("5e36953665fae212939375ab"),
}, {
    '$set': {
        'notes.0.memoryLine.$.hasReviewed': true
    }
});

Upvotes: 0

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17935

You can use arrayFilters in .updateOne() to do this :

db.collection.update({ 'notes.memoryLine._id': ObjectId("5e36953665fae212939375ab") },
    { $set: { "notes.$[].memoryLine.$[element].hasReviewed": true } },
    { arrayFilters: [{ "element._id": ObjectId("5e36953665fae212939375ab") }] })

Note : Since memoryLine is an array inside an object of notes array then this notes.$[] would update all objects memoryLine.hasReviewed to true when criteria is matched, in other case if you wanted to update just first matched object you can use notes.$. Also instead of .updateOne() you can use .updateMany() to update multiple documents.

Upvotes: 1

Related Questions