我有以下Mongoengine文件:
class MyEmbed(EmbeddedDocument):
embedField = StringField(primary_key=True)
varField = StringField()
class TestDoc(Document):
myField = StringField()
embed_list = ListField(EmbeddedDocumentField(MyEmbed))
所以我保留了一个嵌入式文档列表,如果它们不存在,我希望添加新文档。问题是,当我使用原子更新运算符 add_to_set 时,事情并没有像我希望的那样。 这就是我想要做的事情:
embed1 = models.MyEmbed(embedField="F1")
parent = models.TestDoc(myField="ParentField")
embed_list = []
embed_list.append(embed1)
parent.embed_list = embed_list
parent.save()
embed2 = models.MyEmbed(embedField="F1", varField="varField")
TestDoc.objects(id=parent.id).update_one(add_to_set__embed_list=embed2)
问题是,在执行此操作后,我在DB中有一个包含2个元素的嵌入式文档列表。我想要的是决定一个字段(在这种情况下是embedField)2 EmbeddedDocuments是否相等,而不是考虑所有属性。我的问题是:
谢谢!
答案 0 :(得分:2)
实际检查是在MongoDB内完成的,不是 mongoengine。
发送到mongodb的对象应该是相同的,但这是棘手的,因为BSON命令很重要,而python中的字典不是。转换为发送到mongodb mongoengine只需通过字典。这是一个错误 - 所以我添加了#296并将修复为0.8
答案 1 :(得分:-1)
请参阅https://github.com/MongoEngine/mongoengine/blob/master/mongoengine/document.py#L51和https://github.com/MongoEngine/mongoengine/blob/master/mongoengine/base/document.py#L52:
def __eq__(self, other):
if isinstance(other, self.__class__):
return self._data == other._data
return False
它比较了嵌入式文档数据的含义。所以你可以覆盖这个方法。
如果您查看调用QuerySet更新的文档更新(查找add_to_set
和addToSet
),您会发现mongoengine不会检查列表中的存在文档,只需调用mongo $addToSet operation:{ {3}}
在您的代码中,您有文档MyEmbed(embedField="F1")
并尝试添加另一个文档MyEmbed(embedField="F1", varField="varField")
,因此逻辑正确:它添加新文档。如果您尝试下一个代码:
embed1 = models.MyEmbed(embedField="F1")
parent = models.TestDoc(myField="ParentField")
embed_list = []
embed_list.append(embed1)
parent.embed_list = embed_list
parent.save()
embed2 = models.MyEmbed(embedField="F1", varField="varField")
TestDoc.objects(id=parent.id).update_one(add_to_set__embed_list=embed2)
embed3 = models.MyEmbed(embedField="F1")
TestDoc.objects(id=parent.id).update_one(add_to_set__embed_list=embed3)
embed4 = models.MyEmbed(embedField="F1", varField="varField")
TestDoc.objects(id=parent.id).update_one(add_to_set__embed_list=embed4)
您可以发现该父级仅包含embed1
和embed2
。
因此,要解决您的问题,您可以覆盖__eq__
方法并检查列表中的文档,但您必须找到更新文档列表的另一个解决方案,因为它可以直接调用mongo方法。