mongoengine批量upup一批记录?

时间:2015-10-28 10:20:31

标签: python mongodb mongoengine upsert

我想upsert(update or insert) a list of record,事实上我知道mongodb支持bulk操作,因为mongodb3.0。

我想知道mongoenginebulk upsert operation是否支持mongoengine (0.10.0)

如果没有,我想知道如何upsert记录列表,我知道mongoengine支持insert这样批处理:

class User(Document):
    username = StringField(required=True)
    password = StringFiedl(required=True)
    meta = {'db_alias': 'user_info', 'collection': 'user', 
             'indexes': [{'fields': ['username'], 'unique': True}]
           }

def save_users(self, users):
    Users.objects.insert(users) # raise mongoengine.errors.NotUniqueError

2 个答案:

答案 0 :(得分:3)

您实际上可以通过从MongoEngine使用的pymongo驱动程序访问底层集合对象来直接使用bulk operations API。从版本2.6开始,MongoDB本身就支持批量操作。从pymongo驱动程序的v3开始,有更新的方法来访问这些,但是自从相应的驱动程序更新到2.6 Server版本(pymongo 2.7)后,基本方法已经存在。

要通过MongoEngine获取此功能,您可以从类中调用未记录的._get_collection()以返回collection对象:

bulk = Users._get_collection().initialize_ordered_bulk_op()

for user in users:  # where users is a list of dicts containing data to work on
    bulk.find({ "matchField": user['matchField'] }).upsert().replace_one(user)

bulk.execute()

bulk methods的任何其他用法,例如您可能需要的.update_one().upsert()是一种链式方法,可以修改此类更新语句。

你正在使用原始python对象,因为MongoEngine本身没有直接的等价物。但是您可以通过从底层驱动程序访问方法来使用这些操作

答案 1 :(得分:0)

您可以使用mongo.collection.Collection.bulk_write

operations = [
    pymongo.ReplaceOne({'username': user. username}, user.to_mongo(), upsert=True)
    for user in users
]
result = User._get_collection().bulk_write(operations)