The problem of updating multiple embedded documents in MongoDB at the same time

I"m using MongoDB as a database, and today I encountered a problem trying to update multiple embedded documents of a document at the same time.

use environment: Python3.6 PyMongo driver

Table format before update:

{
    "_id" : 0,
    "sys" : {
        "group" : 0,
        "status" : 1,
        "regtime" : NumberLong(1527240646218)
    },
    "info" : {
        "name" : ""
    }
}

updated data that has been generated:

{
    "sys": {
        "group": 0,
        "status": 2
    },
    "info": {
        "name": "",
        "mail": "abc@abc.com",
        "phone": "+1234567"
    }
}

the updated table I need to get:

{
    "_id" : 0,
    "sys" : {
        "group" : 0,
        "status" : 2, // 
        "regtime" : NumberLong(1527240646218)
    },
    "info" : {
        "name" : "",
        "mail": "abc@abc.com", // 
        "phone": "+1234567" // 
    }
}

but when I try to use the $set updater to update the document in the following statement:

database.users.update(
    {"_id": uid},
    {"$set": data} //data
)

but the result is as follows:

{
    "_id" : 0,
    "sys" : {
        "group" : 0,
        "status" : 2 // regtime
    },
    "info" : {
        "name" : "",
        "mail": "abc@abc.com", // 
        "phone": "+1234567" // 
    }
}

after searching on Google, I understand the cause of the problem: using the $set updater will replace the value of the key specified in the document, but the whole embedded document will also be replaced with a new document; if you need to partially update the value of the embedded document, you need to update it like info.$ .

but my table does not have a fixed schema, and the updated data is also generated, so I would like to ask you if there is a direct way to update multiple embedded documents at the same time. Thank you!

Mar.15,2021

your understanding may be wrong. info.$ is an update to matching array elements and has nothing to do with embedded documents.
doesn't know exactly what the data above is. Judging from the result, it should be:

db.users.update({
    "_id": uid
}, {
    'sys.status': data.sys.status,
    'info': data.info
});
Menu