Массовое обновление Mongo не работает

Я пытаюсь выполнить ряд операций обновления в моей MongoDB. Я хотел использовать операцию массового обновления, указанную здесь, но это не работает для меня, используя pymongo. Мой код выглядит следующим образом

import pymongo

client = pymongo.MongoClient()
db = client.test
bulk = db.testCol.initialize_unordered_bulk_op();
bulk.find({"_id":"1,1,1"}).update({"$set":{"attr1":1, "attr2":"X", "attr3":99}})
print bulk.execute()

Результат этого:

{'nModified': 0, 'nUpserted': 0, 'nMatched': 1, 'writeErrors': [], 'upserted': [], 'writeConcernErrors': [], 'nRemoved': 0, 'nInserted': 0}

Насколько я понимаю, Mongo находит документ (nMatched=1), но не обновляет его (nModified=0). Я не могу понять, почему он это делает.

Когда я выполняю операцию вручную, без использования Bulk, вывод кажется правильным, и запись изменяется в соответствии с запросом. Код:

import pymongo

client = pymongo.MongoClient()
db = client.test
print db.testCol.update({"_id":"1,1,1"}, {"attr1":1, "attr2":"X", "attr3":99})

Это действительно работает, что подтверждается как печатью, так и содержимым базы данных.

{'updatedExisting': True, u'nModified': 1, u'ok': 1, u'n': 1}

Я не могу понять, что я делаю неправильно. Насколько я могу судить, я следовал правильной процедуре выполнения массовых обновлений.


person danielvdende    schedule 03.07.2014    source источник
comment
Если ваш существующий документ на самом деле имеет те же значения, которые вы пытаетесь $set, то это не обновление. Новый API распознает это, в отличие от устаревшего ответа о проблеме записи, и сообщает, что документ обновлен.   -  person Neil Lunn    schedule 03.07.2014
comment
Спасибо @NeilLunn! Я думаю, что это действительно была проблема :)   -  person danielvdende    schedule 03.07.2014
comment
Предложить @NeilLunn опубликовать свой ответ в качестве ответа?   -  person MFB    schedule 04.07.2014


Ответы (1)


Я создал служебную функцию, которая выполняет массовые обновления.

def bulk_update(db, collection_name, update_set_where_list):
    """

    :param db: pymongo.database.Database Object
    :param collection_name: Collection name
    :param update_set_where_list:
    :return: full result dictionary
    """
    required_keys = ["where", "set"]
    bulk = db[collection_name].initialize_unordered_bulk_op()

    for update_where_set in update_set_where_list:
        if all(key in update_where_set for key in required_keys):
             bulk.find(update_where_set["where"]).update({"$set": update_where_set["set"]})
        else:
            raise Exception("Required key missing. {}".format(required_keys))

    return bulk.execute()

Например, предположим, что коллекция myCollection в базе данных test должна быть обновлена ​​с помощью y = 3, где x = 1, и y = 6, где x = 5.

Тогда вызов служебной функции выглядит так

client = MongoClient('mongodb://localhost:27017/')
db = client['test']
update_set_where_list = [{"where":{"x":1},"set":{"y":3}},{"where":{"x":5},"set":{"y":6}}]
bulk_update(db=db, collection_name="myCollection", update_set_where_list=update_set_where_list)
person Sunil    schedule 27.07.2016