MongoDB 多个内嵌文档同时更新的问题?

我正在使用MongoDB作为数据库,今天在试图同时更新一个文档的多个内嵌文档时遇到了问题。

使用环境:Python3.6 PyMongo驱动

在更新之前的表格式:

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

已经生成的更新数据:

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

我需要得到的更新之后的表:

{
    "_id" : 0,
    "sys" : {
        "group" : 0,
        "status" : 2, // 这里发生更新
        "regtime" : NumberLong(1527240646218)
    },
    "info" : {
        "name" : "ppp",
        'mail': 'abc@abc.com', // 这里发生更新
        'phone': '+1234567' // 这里发生更新
    }
}

但当我试图使用 $set 更新器在以下语句中更新文档:

database.users.update(
    {"_id": uid},
    {"$set": data} //这里的data代指上面的更新数据
)

但是却得到了这样的结果:

{
    "_id" : 0,
    "sys" : {
        "group" : 0,
        "status" : 2 // 我需要保留的regtime键消失了
    },
    "info" : {
        "name" : "ppp",
        'mail': 'abc@abc.com', // 这里成功更新
        'phone': '+1234567' // 这里成功更新
    }
}

在Google上搜索之后我明白了问题的原因:使用 $set 更新器会对文档中指定的键进行值替换,但是内嵌文档同样会整个全部被提换成新的文档;如果需要部分更新内嵌文档的值需要进行 info.$ 这样的更新。

但是我的表没有固定的模式,更新数据也是生成的,所以想请问大家有没有直接可以同时对多个内嵌文档进行更新的方法。谢谢!

阅读 3k
1 个回答

你的理解可能有误。info.$是对匹配的数组元素的更新,跟内嵌文档没有什么关系。
不知道你上面的data具体内容到底是什么。从结果来看应该是:

data = {
    "sys" : {
        "group" : 0,
        "status" : 2
    },
    "info" : {
        "name" : "桂小方",
        'mail': 'abc@abc.com', // 这里发生更新
        'phone': '+1234567' // 这里发生更新
    }
}

才有可能得到你的结果。如果data确实是这个值,那这个结果是没有问题的。想得到你要的结果,正确的更新语句应该是:

db.users.update({
    "_id": uid
}, {
    'sys.status': data.sys.status,
    'info': data.info
});
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进