0

I'm using mongoengine and I have a collection Question.

class Question(Document):
    id = StringField(primary_key=True)
    answers = EmbeddedDocumentListField(Answer)

class Answer(EmbeddedDocument):
    id = StringField(primary_key=True)
    uid = StringField()
    answer = EmbeddedDocumentField(UserAnswer)

class UserAnswer(EmbeddedDocument):
    status = StringField()

Query to update a Answer document in answers field.

Question.objects(id="question_id", answers__uid="uid").update(set__answers__S__answer__status="new_status")

The above query updates only the first matching document in the answers list.

How can I make it update all matching document in the list?

UPDATE: I tried running the query directly on the mongo shell, it also returned the same result. Is it that because my query is wrong?

yogupta
  • 188
  • 1
  • 3
  • 9
  • I'm not sure about the mongoengine syntax but there is one option in MongoDB update query which you can pass as {multi:true}. This will update multiple documents which are matching with your query part. – Jitendra May 06 '19 at 18:24
  • Yes. mongoengine has [update_one](http://docs.mongoengine.org/apireference.html#mongoengine.queryset.QuerySet.update_one) for single document update and [update](http://docs.mongoengine.org/apireference.html#mongoengine.queryset.QuerySet.update) for multi document update. – yogupta May 07 '19 at 05:19
  • I executed this query `db.question.updateOne({_id:"questionId","answers.uid": "uid",answers.answer.status": "old_status"}, {$set:{"answers.$.answer.status": "new_status"}})` on the shell. I expected this to update the answer status of user `uid`having status `old_status` but it instead updated the first document in array even though it wasn't the matching document. – yogupta May 07 '19 at 07:15

1 Answers1

0

There is no support for it yet in mongoengine but you can achieve it by using raw on update, see this thread: https://github.com/MongoEngine/mongoengine/issues/2019#issuecomment-473706068

UPDATE You have to use the filtered positional operator. In a mongo shell (requires mongo >=3.6), I manage to get it working with

c = db.question
c.update({}, {$set: {'answers.$[i].answer.status': 'new_status'}}, {multi: true, arrayFilters: [ {'i.answer.status': 'old_status'} ]})

You can access the pymongo collection with Question._get_collection(), the pymongo syntax is:

c.update_many({}, {'$set': {'answers.$[i].answer.status': 'new_status'}}, array_filters=[{'i.answer.status': 'old_status'}])
bagerard
  • 5,681
  • 3
  • 24
  • 48
  • Thanks. I tries using `__raw__` but still the same result. also i noticed something with the query. I'll update in the question. – yogupta May 11 '19 at 04:43