Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pull from a list in a dict using mongoengine

I have this Document in mongo engine:

class Mydoc(db.Document):
    x = db.DictField()
    item_number = IntField()

And I have this data into the Document

{
    "_id" : ObjectId("55e360cce725070909af4953"),
    "x" : {
        "mongo" : [
            {
                "list" : "lista"
            },
            {
                "list" : "listb"
            }
        ],
        "hello" : "world"
    },
    "item_number" : 1
}

Ok if I want to push to mongo list using mongoengine, i do this:

Mydoc.objects(item_number=1).update_one(push__x__mongo={"list" : "listc"})

That works pretty well, if a query the database again i get this

{
    "_id" : ObjectId("55e360cce725070909af4953"),
    "x" : {
        "mongo" : [
            {
                "list" : "lista"
            },
            {
                "list" : "listb"
            },
            {
                "list" : "listc"
            }
        ],
        "hello" : "world"
    },
    "item_number" : 1
}

But When I try to pull from same list using pull in mongo engine:

Mydoc.objects(item_number=1).update_one(pull__x__mongo={'list': 'lista'})

I get this error:

mongoengine.errors.OperationError: Update failed (Cannot apply $pull to a non-array value)

comparising the sentences:

Mydoc.objects(item_number=1).update_one(push__x__mongo={"list" : "listc"}) # Works
Mydoc.objects(item_number=1).update_one(pull__x__mongo={"list" : "listc"}) # Error

How can I pull from this list?

I appreciate any help

like image 605
oskararenas Avatar asked Oct 30 '22 20:10

oskararenas


1 Answers

I believe that the problem is that mongoengine doesn't know the structure of your x document. You declared it as DictField, so mongoengine thinks you are pulling from DictField not from ListField. Declare x as ListField and both queries should work just fine.

I suggest you should also create an issue for this:
https://github.com/MongoEngine/mongoengine/issues

As a workaround, you can use a raw query:

Mydoc.objects(item_number=1).update_one(__raw__={'$pull': {'x.mongo': {'list': 'listc'}}})
like image 157
matino Avatar answered Nov 08 '22 03:11

matino