ドキュメントの既存の構造で解決する方法がわからないというシナリオに出くわしました。以下に示すように、リファクタリングでこの問題を明らかに解決できますが、これが可能な限り最も効率的に解決され、同じ構造を尊重する方法に興味があります。
この質問は、MongoEngine の ListField の EmbeddedDocument をアトミック更新する方法とは異なることに注意してください。
次のモデルがあるとします。
class Scans(mongoengine.EmbeddedDocument):
peer = mongoengine.ReferenceField(Peers, required=True)
site = mongoengine.ReferenceField(Sites, required=True)
process_name = mongoengine.StringField(default=None)
documents = mongoengine.ListField(mongoengine.ReferenceField('Documents'))
is_complete = mongoengine.BooleanField(default=False)
to_start_at = mongoengine.DateTimeField()
started = mongoengine.DateTimeField()
finished = mongoengine.DateTimeField()
class ScanSettings(mongoengine.Document):
site = mongoengine.ReferenceField(Sites, required=True)
max_links = mongoengine.IntField(default=100)
max_size = mongoengine.IntField(default=1024)
mime_types = mongoengine.ListField(default=['text/html'])
is_active = mongoengine.BooleanField(default=True)
created = mongoengine.DateTimeField(default=datetime.datetime.now)
repeat = mongoengine.StringField(choices=REPEAT_PATTERN)
scans = mongoengine.EmbeddedDocumentListField(Scans)
私がやりたいのは、スキャン フィールドのすべての要素 (スキャン埋め込みドキュメントのリスト) のドキュメント リストが一意である場合にのみ、ScanSettings オブジェクトを挿入することです。一意とは、リスト全体ではなく、データベース レベルのリスト内のすべての要素を意味します。これは簡単です。
簡単に言うと、ScanSetting を挿入するときに、スキャン リストのいずれかの要素に、ドキュメントのリストが重複しているスキャンのインスタンスがある場合、そのような挿入は行われません。データベースレベルでの一意性を意味し、既存のレコードがあればそれを考慮に入れます。
Mongo が同じドキュメント内のリストのすべての要素で一意性をサポートしていないことを考えると、2 つの解決策が見つかりました。
オプション A
「スキーマ」をリファクタリングし、Scans コレクションを Embedded ドキュメントではなく Document から継承させ、ScanSettings の scans フィールドを ReferenceFields の ListField から Scans ドキュメントに変更します。次に、演算子「add_to_set」とオプション「upsert = True」を使用して「Updates」を使用して最初にスキャンを保存するだけでよいので簡単です。次に、操作が承認されたら、ScanSettings を保存します。+ 1 クエリを挿入するには、スキャン インスタンスの数が必要になります。
オプション B 同じ「スキーマ」を保持しますが、どういうわけかスキャンの埋め込みドキュメントに一意の ID を生成します。次に、空でないスキャン フィールドを使用してスキャン設定を挿入する前に、既存のレコードを取得して、取得したレコードと挿入するレコードの間に重複するドキュメントの ObjectId があるかどうかを確認します。つまり、MogoneEngine/Mongodb を使用するのではなく、Python を使用して一意性をチェックします。挿入するスキャン インスタンスの数 x 2 (読み取り + add_set_operator による更新) + 1 つの ScanSettings 保存が必要です。
オプション C 一意性を無視します。私のモデルがどのように構築されるかを考えると、重複がないか、重複があるとしても無視できると確信しています。次に、読み取り時に重複を処理します。私のようにリレーショナル データベースから来ている人にとって、このソリューションは難航しているように感じます。
私はMongoの初心者なので、コメントに感謝します。ありがとう。
PS: 最新の MongoEngine と無料の Mongodb を使用しています。
よろしくお願いします。