简体   繁体   中英

Update nested property by condition in MongoEngine

I have MonogoDB collection described with following MongoEngine document:

class Inner(EmbeddedDocument):
    value = StringField()

class Outer(Document):
    inner = EmbeddedDocumentListField(Inner)

So db.outer collection in MongoDB can look like this:

{ "inner": [{ "value": "A" }, { "value": "B" }] },
{ "inner": [{ "value": "B" }] },
{ "inner": [] }

Now, I would like to update all inner.value , where old value is "B" to "C", so desired result is:

{ "inner": [{ "value": "A" }, { "value": "C" }] },
{ "inner": [{ "value": "C" }] },
{ "inner": [] }

In native MongoDB, I can use this query:

db.outer.updateMany(
    {},
    { "$set": { "inner.$[current].value": "C" }},
    { "arrayFilters": [{ "current.value": "B" }]}
)

Is there any way to do that in MongoEngine? And if no, can I somehow run native updateMany query? I know only about aggregation ( Outer.objects.aggregate ).

I found this not very clean (_get_collection should not be public) solution:

Outer._get_collection().update_many(
   {},
   {"$set": {"inner.$[current].value": "C"}},
   array_filters=[{"current.value": "B"}]
)

A cleaner way to do this is to use __raw__ , that would allow passing any mongo conditions when working with mongoengine tables - see more here: https://docs.mongoengine.org/guide/querying.html#raw-queries

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM