Mongoengine: How to append a new document to an Embedded ListField document?
Asked Answered
I

1

10

I would like to append a new ListField EmbeddedDocument to an existing ListField EmbeddedDocument document. In other words appending a new document to list that belongs to a a document in list.

My Model: A Post can contain several Comments, each comment can have several Likes:

class Post(Document):
    txt = StringField()
    comments = ListField(EmbeddedDocumentField(Comment))

class Comment(EmbeddedDocument):
    comment = StringField()
    comment_id = ObjectIdField()
    likes = ListField(EmbeddedDocumentField(Like))

class Like(EmbeddedDocument):
    user = ReferenceField(User)
    date = DateTimeField(default=datetime.utcnow,required=True)

My Code: (it's not working 'append' command dosen't exists, only 'set' exists)

def appendNewLike():
    user = {..}
    target = ObjectId(commentId)
    newLike = Like(user=user)
    Product.objects(comments__comment_id=target).update(append_comments__S__likes=newLike)

Ideal solution would be something like:

def appendNewLike():
    user = {..}
    target = ObjectId(commentId)
    newLike = Like(user=user)
    Product.objects(comments__comment_id=target).comments.likes.append(newLike)

Comments? Suggestions?

Insight answered 7/2, 2013 at 2:25 Comment(0)
S
5

You want to $push an new item to the list eg:

Post.objects(comments__comment_id=target).update(
    push__comments__S__likes=newLike
)

However, there are bigger issues here. The schema is not ideal - ever growing arrays might cause issues as the document grows it will have to be moved on disk to a new extent (so it can fit), if its continually growing then that will impact performance.

See the data modeling docs for more information.

Setter answered 8/2, 2013 at 12:10 Comment(2)
Hello, push doesn't work until i call reload() with class instance. like product = Product() Product.objects(comments__comment_id=target).update( push__comments__S__likes=newLike) product.reload()Lophobranch
@Lophobranch If I execute Product.objects(...).update(push...) and do a refresh on Mongo Atlas side, this update is commited correctly. No need of product.reload()Horatio

© 2022 - 2024 — McMap. All rights reserved.