avtpg
avtpg

Reputation: 3

Update a document field with multiple nested documents

I have an existing MongoDB document that contains the field files(as well as other fields). The files field is an object and now I want to update this field with several nested documents. I have been successful in inserting one nested document with the following syntax:

db.collection.updateOne(
    { "id": 1 },
    {
        $set: {
            "files":
            {
                "filename1": {
                    "a": "Lorem ipsum dolor",
                    "b": "Sit amet consectetur",
                    "c": "Adipiscing elit"
                }
            }
        }
    })

Next, I tried inserting 2 more documents at the same time into the file field which failed

db.collection.updateOne(
    { "id": 1 },
    {
        $set: {
            "files":
            {
                "filename2": {
                    "d": "Lorem ipsum dolor",
                    "e": "Sit amet consectetur",
                    "f": "Adipiscing elit"
                }
            }
{
        "filename3": {
            "g": "Duis aute irure",
            "h": "Labore et dolore",
            "i": "Eiusmod tempor incididunt"
        }
    }
}})

After this didn't work, I attempted to insert the records one by one using the first code block, but inserting filename2 (I did not want to overwrite existing filename1). This document was inserted into the files object but overwrote the existing document filename1. I tried several different variations but nothing has worked.

Any feedback/assistance regarding how to nest several documents within a field would be helpful.

Upvotes: 0

Views: 402

Answers (1)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17915

It didn't work because your update query has few issues, check this :

db.collection.updateOne(
    { "id": 1 },
    {
        $set: {
            "files":
            {
                "filename2": {
                    "d": "Lorem ipsum dolor",
                    "e": "Sit amet consectetur",
                    "f": "Adipiscing elit"
                },
                "filename3": {
                    "g": "Duis aute irure",
                    "h": "Labore et dolore",
                    "i": "Eiusmod tempor incididunt"
                }
            }
        }
    })

Above query would work but there is an issue here - it would replace the existing files field with the new files being sent since you're using $set which would replace the existing field with new value(If old value is different compared to new value).

If filesis an array you can use $push or $addToSet to add new values to existing files field(Then you would just replace $set with one of these it will work), but if you wanted to have files as an object, either your need to read it and inject new values using . notation in code & write the whole files back to MongoDB using $set, which is two calls to DB. In the other way you can do it in one DB call by this :

db.updateObject.updateOne({"id": 1}, {
    $set: {
       /** Same like programming language you use `.`,
           You're not replacing files rather you're adding new objects to files,
           If 'files.filename2' already exists in DB then it would be updated. */
        'files.filename2': {
            "d": "Lorem ipsum dolor",
            "e": "Sit amet consectetur",
            "f": "Adipiscing elit"
        }, 'files.filename3': {
            "g": "Duis aute irure",
            "h": "Labore et dolore",
            "i": "Eiusmod tempor incididunt"
        }
    }
})

Which would update the files object with two new objects in it :

/* 1 */
{
    "_id" : ObjectId("5e179dac627ef7823643cd97"),
    "id" : 1,
    "files" : {
        "filename1" : {
            "a" : "Lorem ipsum dolor",
            "b" : "Sit amet consectetur",
            "c" : "Adipiscing elit"
        },
        "filename2" : {
            "d" : "Lorem ipsum dolor",
            "e" : "Sit amet consectetur",
            "f" : "Adipiscing elit"
        },
        "filename3" : {
            "g" : "Duis aute irure",
            "h" : "Labore et dolore",
            "i" : "Eiusmod tempor incididunt"
        }
    }
}

Upvotes: 1

Related Questions