Как мне обновить документ Mongo после его вставки?

83

Допустим, я вставляю документ.

post = { some dictionary }
mongo_id = mycollection.insert(post)

Теперь предположим, что я хочу добавить поле и обновить его. Как я могу это сделать? Похоже, это не работает ...

post = mycollection.find_one({"_id":mongo_id}) 
post['newfield'] = "abc"
mycollection.save(post)
TIMEX
источник

Ответы:

108

В pymongo вы можете обновить с помощью:
mycollection.update({'_id':mongo_id}, {"$set": post}, upsert=False)
параметр Upsert будет вставлять вместо обновления, если сообщение не найдено в базе данных.
Документация доступна на сайте mongodb .

ОБНОВЛЕНИЕ Для версии> 3 используйте update_one вместо update :

mycollection.update_one({'_id':mongo_id}, {"$set": post}, upsert=False)

аллайт
источник
1
@ Эллиотт - какая еще альтернатива?
ajayramesh
29
mycollection.find_one_and_update({"_id": mongo_id}, 
                                 {"$set": {"newfield": "abc"}})

должен отлично работать для вас. Если нет документа с идентификатором mongo_id, он не удастся, если вы также не используете upsert=True. По умолчанию возвращается старый документ. Чтобы получить новый, пройдите return_document=ReturnDocument.AFTER. Все параметры описаны в API .

Метод был представлен для MongoDB 3.0. Он был расширен до версий 3.2, 3.4 и 3.6.

serv-inc
источник
2
Это также работает, если вы добавляете "_id" в другое поле, например "username" fyi
Chris
1
@Chris Когда вы говорите «текущее пимонго», у тех из нас, кто живет в будущем, может не быть той же версии. Приятно быть конкретным.
Mnebuerquo
@Mnebuerquo, это отличный момент, которого я бы иначе не увидел. Сделаю в будущих постах, спасибо.
Крис
@Chris Редактирование очень помогает. Благодаря! И спасибо от будущего-меня, когда я забываю об этом и снова ищу!
Mnebuerquo
22

Я буду использовать collection.save(the_changed_dict)этот способ. Я только что протестировал это, и он все еще работает у меня. Следующее цитируется непосредственно из pymongo doc.:

save(to_save[, manipulate=True[, safe=False[, **kwargs]]])

Сохраните документ в этой коллекции.

Если to_save уже имеет «_id», то выполняется операция update () (upsert), и любой существующий документ с этим «_id» перезаписывается. В противном случае выполняется операция insert (). В этом случае, если для параметра "Manage" установлено значение "Истина", к to_save будет добавлен "_id", и этот метод вернет "_id" сохраненного документа. Если для параметра "Manage" установлено значение "Ложь", сервер добавит "_id", но этот метод вернет None.

Andrew_1510
источник
9

Это старый вопрос, но я наткнулся на него, когда искал ответ, поэтому я хотел дать обновленный ответ для справки.

Методы saveи updateустарели.

save (to_save, manage = True, check_keys = True, ** kwargs) ¶ Сохранить документ в этой коллекции.

УСТАРЕЛО - используйте вместо этого insert_one () или replace_one ().

Изменено в версии 3.0: Убран безопасный параметр. Передайте w = 0 для неподтвержденных операций записи.

update (spec, document, upsert = False, manage = False, multi = False, check_keys = True, ** kwargs) Обновить документ (ы) в этой коллекции.

УСТАРЕЛО - используйте replace_one (), update_one () или update_many () вместо этого.

Изменено в версии 3.0: Убран безопасный параметр. Передайте w = 0 для неподтвержденных операций записи.

в частном случае OP лучше использовать replace_one.

ThinkBonobo
источник
9

Согласно последней документации о PyMongo под названием Insert a Document (вставка устарела) и следующему защитному подходу, вы должны вставить и обновить следующим образом:

result = mycollection.insert_one(post)
post = mycollection.find_one({'_id': result.inserted_id})

if post is not None:
    post['newfield'] = "abc"
    mycollection.save(post)
Гюроль Канбек
источник