Извлечь из списка в dict с помощью mongoengine

У меня есть этот документ в движке mongo:

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

И у меня есть эти данные в документе

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

Хорошо, если я хочу нажать на список mongo с помощью mongoengine, я делаю это:

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

Это работает очень хорошо, если снова запросить базу данных, я получаю это

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

Но когда я пытаюсь вытащить из того же списка, используя механизм pull in mongo:

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

Я получаю такую ​​ошибку:

mongoengine.errors.OperationError: Ошибка обновления (невозможно применить $ pull к значению, не являющемуся массивом)

сравнивая предложения:

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

Как я могу вытащить из этого списка?

Я ценю любую помощь


person oskararenas    schedule 30.08.2015    source источник


Ответы (1)


Я считаю, что проблема в том, что mongoengine не знает структуру вашего x документа. Вы указали это как DictField, поэтому mongoengine думает, что вы используете DictField, а не ListField. Объявите x как ListField, и оба запроса должны работать нормально.

Я предлагаю вам также создать проблему для этого:
https://github.com/MongoEngine/mongoengine/issues

В качестве обходного пути вы можете использовать необработанный запрос:

Mydoc.objects(item_number=1).update_one(__raw__={'$pull': {'x.mongo': {'list': 'listc'}}})
person matino    schedule 01.09.2015
comment
Спасибо, raw работает неплохо, также лучше использовать синтаксис mongodb. - person oskararenas; 07.09.2015