arrayFilters оно не функционирует с pymongo, но если в консоли MongoDB

У меня есть этот код в Пайтоне

from pymongo import MongoClient

db       = MongoClient('localhost', 27017)['myDB']['myCol']
params   = { "model": "ILX ACURA" }
asset    = { "newAsset": ["Foo", "Bar", "Poo"] }
document = { "$push": { "models.$[mod].years": asset } }
filters  = { "arrayFilters" : [ { "mod.model": params['model'] } ] }
updated  = db.update( {}, document, False, False, None, filters )

if updated.matched_count > 0:
    print 'DONE!'

Когда я скроллирую рукописный шрифт, у меня появляется эта ошибка

WriteError: Не array filter found for identifier 'mod' in path models.$ [mod] .years

Я боролся с Пайтоном много времени и это попробовал лучше в консоли MongoDB

db.myCol.updateOne({}, { $push: { "models.$[mod].years": { "newAsset": ["Foo", "Bar","Poo"] } } }, { arrayFilters: [ { "mod.model": "ILX ACURA" } ] } )

Сюрприз!

{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1 }

Что будет происходить?

Использовал python 2.7 pymongo 3.8 mongoDB 4.0

7
задан 09.08.2019, 18:19
1 ответ

Как довольно индийская @JackNavaRow в Вашем уместном комментарии, фильтры, которые ты применяешь, должны быть перемещенными в списке и не в документе, как это у тебя есть, однако это не único проблема.

Según documentaci¦n PyMongo método update estÃ: устаревший ( deprecated ) , и он предлагает себе использовать один из них métodos: replace_one, update_one или update_many.

Мы Используем update_one и podrÃ: s реализовывать задание, ademÃ: s я предлагаю тебе каждый раз, когда ты попробовал реализовывать операции на базе данных использовать блоки try except

Твой c¦digo podr¦, - чтобы оставаться следующей формы:

from pymongo import MongoClient

db       = MongoClient('localhost', 27017)['myDB']['myCol']
params   = { "model": "ILX ACURA" }
asset    = { "newAsset": ["Foo", "Bar", "Poo"] }
# llamamos update al documento que representa la actualización, así no hay confusión
# con el documento que se está actualizando
update = { "$push": { "models.$[mod].years": asset } }
# filters es una lista, no un documento, cada elemento de la lista define un filtro
filters  = [ { "mod.model": params['model'] } ]

#usamos un bloque try except
try:
    updated  = db.update_one( {}, update, False, False, None, filters )
    if updated.matched_count > 0:
        print 'DONE!'
except Exception, e:
    print str(e)

С этим deber¦, - когда функционирует то, что ты пробуешь реализовать (для 1 документа).

Edici¦n

Dado que, как кажется, твой intenci¦n состоит в том, чтобы обновлять несколько документов, ты должен использовать update_many.

Твой c¦digo меняется, так как порядок аргументов, перемещенных в método отличается. Ты можешь консультировать documentaci¦n .

from pymongo import MongoClient

db       = MongoClient('localhost', 27017)['myDB']['myCol']
params   = { "model": "ILX ACURA" }
asset    = { "newAsset": ["Foo", "Bar", "Poo"] }
# llamamos update al documento que representa la actualización, así no hay confusión
# con el documento que se está actualizando
update = { "$push": { "models.$[mod].years": asset } }
# filters es una lista, no un documento, cada elemento de la lista define un filtro
filters  = [ { "mod.model": params['model'] } ]

#usamos un bloque try except
try:
    # usamos update_many
    updated  = db.update_many( {}, update, False, filters )
    if updated.matched_count > 0:
        #si deseamos ver la cantidad de documentos afectados:
        print updated.matched_count
        print 'DONE!'
except Exception, e:
    print str(e)

Надеялся, что это - то, что ты искал.

5
ответ дан 01.12.2019, 22:19
  • 1
    @JackNavaRow Устаревший - update (это был тот, которого использовал OP в Вашем вопросе). Я предлагаю ему использовать update_one, или update_many, завися, если он хочет изменить 1 документ или многий. – Mauricio Contreras 13.08.2019, 16:27

Теги

Похожие вопросы