使用MongoEngine替换ListField中的值

时间:2019-06-12 12:42:41

标签: mongoengine

我正在使用MongoEngine创建脚本来更新集合。此更新需要修改ListField中的特定字段。
使用原始的pyMongo,更新如下所示:

db.books.update({"authors": {"$elemMatch": {"$eq": "matt"}}}, {'$set': {"authors.$": "Mathew"}}).

不幸的是,我必须在MongoEngine中执行此操作(由于系统的其余部分都可以使用,并且我需要它以保持一致性),并且由于这可能是一个非常大的集合,因此我更喜欢mongo处理更新而不是加载整个集合并在我的python代码中更新书籍的每个元素。

我尝试使用Mongo Engine进行相同的请求:

class Book(DynamicDocument):
    meta = {'collection': 'books', 'strict': False}

    authors = ListField()

    @classmethod
    def update_author_name(cls, oldVal, newVal):
        filter = Q(**{"authors__in": [oldVal]})
        cls.objects(filter).update(**{authors+".$": newVal})

但是,我得到一个例外:

{InvalidQueryError}field names cannot contain dots (".") or null characters ("\0"), and they must not start with a dollar sign ("$").

1 个答案:

答案 0 :(得分:1)

mongoengine不支持此功能,最好的方法是使用raw并更接近pymongo语法,如下所示:

Book.objects(__raw__={"authors": {"$elemMatch": {"$eq": "Math"}}}).update(__raw__={'$set': {"authors.$": "Mathew"}})

但是与通过pymongo进入实际集合并执行查询相比,没有太多的附加值

c = Book._get_collection()
c.update({"authors": {"$elemMatch": {"$eq": "matt"}}}, {'$set': {"authors.$": "Mathew"}})