Как вставить после элемента в ListField с mongoengine в Python? - PullRequest
0 голосов
/ 09 мая 2019

Я хочу добавить элемент в ListField. Вот мой код:

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

class Comment(EmbeddedDocument):
    comment = StringField()
    comment_id = StringField()
    ...

...

insert_id = "3000"

update_comment_str = "example"

#query
post_obj = Post.objects(_id=str(_id)).first()

#find the element's position and update
position = 0
for position,_ in enumerate(post_obj.comments):
    if post_obj.comments[position].comment_id = insert_id:
        break;

post_obj.comments.insert(position+1,Comment(comment_id=str(len(post_obj.comments)+1),comment=update_comment_str)

#save
post_obj.save()

Это медленно, потому что я извлекаю весь документ в экземпляр Python. Затем я сохраняю документ. Как его оптимизировать?

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Я полагаю, что вы можете сделать это с помощью оператора push mongoengine.Например:

post = Post(comments=[Comment(comment='a'), Comment('c')]).save()
Post.objects(id=post.id).update(push__comments__1=[Comment(comment='b')])

Post.objects.as_pymongo() # [{u'_id': ObjectId('5cd49aa24ec5dc4cd7f5bbc8'), u'comments': [{u'comment': u'a'}, {u'comment': u'b'}, {u'comment': u'c'}]}]

Если вы заранее не знаете позицию, вы можете использовать агрегированный запрос, чтобы сначала найти ее:

# Find position
projection = {"index": { "$indexOfArray": [ "$comments.comment", 'c' ] }}
data = list(Post.objects(id=post.id).aggregate(
        {'$project': projection}))
position = data[0]['index']
# Push at position
key = "push__comments__{}".format(position)
Post.objects(id=post.id).update(**{key: [Comment(comment='b')]})
0 голосов
/ 09 мая 2019

в PyMongo есть метод под названием bulk_write для вызова операций обновления / вставки / удаления (http://api.mongodb.com/python/current/examples/bulk.html). К сожалению, он не поддерживается в MongoEngine. Но, тем не менее, вы можете комбинировать pymongo и MongoEngine.

...