简体   繁体   中英

Update value in array of string on array of objects mongodb

I'm trying to update a value of a array of strings in mongodb, which is inside of another array of objects

here is an example of the model

{ 
    "_id" : ObjectId("5a8cd02f87d4839d279f6559"), 
    "category" : "0",
    "email" : "doctor@doctor.com",
    "password" : "doctor",
    "name" : "doctor",
    "directorys" : [ { 
                       "path" : "doctor@doctor.com/own/", 
                       "files" : [ "" ] 
                     }, 
                     {
                       "path" : "doctor@doctor.com/modified/",
                       "files" : [ "" ] 
                     },
                     { 
                      "path" : "doctor@doctor.com/own/pacient1", 
                      "files" : [ "", "README.txt" ] 
                     } 
                   ] }
}

So im trying to update the name "README.txt" to "README2.txt" but i'm struggling with mongo

i tried this

db.users.update({"email":"doctor@doctor.com","directorys.files":"README.txt"},{"$set":{"directorys.files.$":"README2.txt"}})

but throws the following error

WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 16837,
        "errmsg" : "cannot use the part (directorys of directorys.files.2) to traverse the element ({directorys: [ { path: \"doctor@doctor.com/own/\", files: [ \"\" ] }, { path: \"doctor@doctor.com/modified/\", files: [ \"\" ] }, { path: \"doctor@doctor.com/own/pacient1\", files: [ \"\", \"README.txt\" ] } ]})"
    }
})

what i am missing? i dont know what to do

Well i could update the element in the array doing the following command

db.users.update({"directorys.files":"README.txt","email":"doctor@doctor.com"},{"$set":{"directorys.$.files.1":"README2.txt"}})

I have to do some server side work to get that number "1" dinamycally but that resolves my question.

I got inspiration from here https://dba.stackexchange.com/questions/114329/mongodb-update-object-in-array

Since directorys is an array, I think you need an array operator there as well. Try this query:

db.users.update(
    {"email":"doctor@doctor.com","directorys.files":"README.txt"},
    {"$set":{"directorys.$[selectedFiles].files.$":"README2.txt"}},
    {arrayFilters: [{"selectedFiles.files": "README.txt"}]}
)

You can see more about arrayFilters here: https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#up. S []

ArrayFilters allows you to take an array, select only those elements that match a certain criteria, and then apply $set (or any other update / upsert operator) to just those elements.

One thing though is that this will only update the first element of your files array that has README.txt. If README.txt is present more than once, you won't update all of them. If you want to update all elements in the array that are README.txt, you need a second arrayFilter, like this:

db.users.update(
    {"email":"doctor@doctor.com","directorys.files":"README.txt"},
    {"$set":{"directorys.$[selectedDirs].files.$[selectedFiles]":"README2.txt"}},
    {arrayFilters: [{"selectedDirs.files": "README.txt"}, {"selectedFiles": "README.txt"}]}
)

That should select all directorys elements with a files array that has at least one README.txt, then select all elements within that files array that equals README.txt, and then set those elements to README2.txt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM