我正在尝试在 mongoengine 中执行upsert函数。也就是说,如果存在一个文档,我想用新值更新它,而如果不存在,我想创建并插入。
我有对象列表。这些对象可以具有或不能具有ObjectId。 示例是:
[
{
"id" : ObjectId("5c1791b7397df4a9c8518342"),
"type": "Line"
},
{
"type": "Line"
}
]
如您所见,第二个对象没有ID。
我将查询写为:
updates = Collection.objects(
id=obj.get('id', None)).modify(
new=True,
upsert= True,
**update_dict
)
当我遍历列表时, obj
是每个对象。
注意:update_dict
是另一个字典,它从返回要设置的属性的函数中获取其值。 (例如:set__type:“ Line”)
问题
第一个对象被修改就好了。但是有一个错误:
“'None'不是有效的ObjectId,它必须是12字节的输入或 24个字符的十六进制字符串”
显然是因为obj.get('id', None)
部分。
因此,是否可以将ID传递为None来生成ID?
答案 0 :(得分:0)
我用猫鼬和nodejs尝试了同样的事情,如果我像下面这样使用它,它对我有用:
这是我的数组对象:
var arr = [
{
_id: "5c13de7d47zfe91e3484362f",
email: 'test1@gmail.com',
},
{
_id: "5c13de7d47zfe91e3484362f",
email: 'test2@gmail.com',
},
{
// _id: "5c66aa87751fz5368759f9bc", // Commented
email: 'test3@gmail.com',
}
]
现在我正在使用nodejs遍历数组,如下所示。
arr.forEach(async element => {
await Driver.findOneAndUpdate(
{
_id: Types.ObjectId(element._id)
},
{
email: element.email
},{ upsert: true, new: true }
).lean().exec();
});
它对我有用。它会在前两种情况下更新文档,并为后一种情况插入新文档。
最主要的是使用Types.ObjectId
,它用于指定ObjectId的类型。如果我在未指定Schema.Types.ObjectId
的情况下执行此操作,则它将不起作用。