I am trying to define methods for performing checks and updates to a listfield of embedded documents in mongoengine. What is the proper way of doing what I'm trying to do. The code is below.
class Comment(EmbeddedDocument):
created = DateTimeField()
text = StringField()
class Post(Document):
comments = ListField(EmbeddedDocumentField(Comment))
def check_comment(self, comment):
for existing_comment in self.comments:
if comment.created == existing_comment.created and
comment.text == existing_comment.text:
return True
return False
def add_or_replace_comment(self, comment):
for existing_comment in self.comments:
if comment.created == existing_comment.created:
# how do I replace?
# how do I add?
Is this even the correct way to go about something like this?
You could use an EmbeddedDocumentListField instead of a list of embedded documents. That way you get access to some handy methods like filter, create or update:
class Comment(EmbeddedDocument):
created = DateTimeField()
text = StringField()
class Post(Document):
comments = EmbeddedDocumentListField(Comment)
...
def add_or_replace_comment(self, comment):
existing = self.comments.filter(created=comment.created)
if existing.count() == 0:
self.comments.create(comment)
else:
existing.update(comment)
(code not tested)
You need to find the index of the existing comment.
You can then overwrite the old comment with the new comment (where i is the index) eg:
post.comments[i] = new_comment
then just do a post.save()
and mongoengine will convert that to a $set
operation.
Alternatively, you could just write the $set
eg:
Post.objects(pk=post.pk).update(set__comments__i=comment)
来源:https://stackoverflow.com/questions/7279355/what-is-the-proper-way-to-update-a-listfield-of-embedded-documents-in-mongoengin