0

次の 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 つの要素を持つ埋め込みドキュメントのリストがあることです。そして、私が望むのは、すべてのプロパティを考慮に入れるのではなく、2 つの EmbeddedDocuments が等しいかどうかを 1 つのフィールド (この場合はembedField) で決定することです。私の質問は次のとおりです。

  • 2つのEmbeddedDocumentsが等しいかどうかをMongoengineが判断するデフォルトの基準は何ですか?
  • 2 つの EmbeddedDocuments が等しいかどうかを Mongoengine に判断させる関数を再定義するにはどうすればよいですか?

ありがとう!

4

2 に答える 2

3

実際のチェックは、mongoengine では なくMongoDB 内で行われます。

mongodb に送信されるオブジェクトは同じである必要がありますが、これは BSON の順序が重要であり、辞書を使用する Python では重要ではないため、注意が必要です。mongodb に送信するように変換する場合、mongoengine は辞書を渡すだけです。これはバグです - #296を追加し、0.8 で修正します

于 2013-04-26T09:20:52.223 に答える
-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

埋め込みドキュメント データの辞書を比較します。したがって、このメソッドをオーバーライドできます。

add_to_setQuerySet update (find and )を呼び出す Document update を見るとaddToSet、mongoengine がリストに存在するドキュメントをチェックせず、mongo $addToSet 操作を呼び出すだけであることがわかります: https://github.com/MongoEngine/mongoengine/blob/master /mongoengine/queryset/transform.py#L156 .

コードにドキュメントが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 メソッドを直接呼び出すため、ドキュメント リストを更新する別の解決策を見つける必要があります。

于 2013-04-25T07:35:33.020 に答える