Mongoengine如何判断2个EmbeddedDocuments是否相等?

时间:2013-04-24 13:34:43

标签: mongodb mongoengine

我有以下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是否相等,而不是考虑所有属性。我的问题是:

  • Mongoengine决定2个EmbeddedDocuments是否相同的默认标准是什么?
  • 如何重新定义Mongoengine在2个EmbeddedDocuments相等时决定的功能?

谢谢!

2 个答案:

答案 0 :(得分:2)

实际检查是在MongoDB内完成的,不是 mongoengine。

发送到mongodb的对象应该是相同的,但这是棘手的,因为BSON命令很重要,而python中的字典不是。转换为发送到mongodb mongoengine只需通过字典。这是一个错误 - 所以我添加了#296并将修复为0.8

答案 1 :(得分:-1)

请参阅https://github.com/MongoEngine/mongoengine/blob/master/mongoengine/document.py#L51https://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_setaddToSet),您会发现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)

您可以发现该父级仅包含embed1embed2

因此,要解决您的问题,您可以覆盖__eq__方法并检查列表中的文档,但您必须找到更新文档列表的另一个解决方案,因为它可以直接调用mongo方法。