使用 MongoEngine 替换 ListField 中的值

Using MongoEngine to replace a value within a ListField

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

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

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

我尝试用 Mongo 引擎做同样的请求:

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 ("[=12=]"), and they must not start with a dollar sign ("$").

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"}})