AWS DocumentDB 语法与 UpdateMany 的 MongoDB 不同

AWS DocumentDB Syntax differs from MongoDB for UpdateMany

从 mongo > documentDB 迁移后,我尝试使用 substr 执行更新,但是我收到一个奇怪的错误。

以下使用 pymongo 在 Mongo 4.0 上工作:

    await db[cls.colname].update_many(
        {'$or': [{'preview_title': {'$exists': False}}, {'preview_title': None}]},
        [{'$set': {'preview_title': {'$substr': ['$title', 0, 70]}}}],
    )

等效的 mongo shell 命令也有效:

db.getCollection('pages').updateMany({'$or': [{'preview_title': {'$exists': false}}, {'preview_title': null}]}, [{'$set': {'preview_title': {'$substrBytes': ['$title', 0, 70]}}}])

但是,在切换到 AWS DocumentDB 后,它不接受更新作为数组,否则它会 return 这个错误:“Mongo错误:参数 u 的类型错误” image

如果我将命令更改为以下,它将起作用(基本上只是从更新部分删除方括号):

db.getCollection('pages').updateMany({'$or': [{'preview_title': {'$exists': false}}, {'preview_title': null}]}, {'$set': {'preview_title': {'$substr': ['$title', 0, 70]}}})

这很好,但是,等效的 pymongo 调用似乎不起作用:

await db[cls.colname].update_many(
            {'$or': [{'preview_title': {'$exists': False}}, {'preview_title': None}]},
            {'$set': {'preview_title': {'$substr': ['$title', 0, 70]}}},
        )

return出现以下错误: pymongo.errors.WriteError:文档不能有 $ 前缀字段名称:$substr

将数组作为更新传递称为“使用聚合管道更新”。 DocumentDB 显然没有实现这一点(在许多其他 MongoDB 功能中)。

当您从更新中删除数组时,您将不再使用 https://docs.mongodb.com/manual/reference/operator/aggregation/set/ to using https://docs.mongodb.com/manual/reference/operator/update/set/。您会注意到更新 $set 不接受像聚合 $set 那样的表达式。因此,您使用 $set 进行的 shell 更新会将(嵌套的)文档 {'$substr': ['$title', 0, 70]} 写入 preview 字段。通常以美元开头的键是不可查询的,因为美元前缀被 MongoDB 运算符使用,因此将这样的文档写入字段是一个坏主意。 Pymongo 告诉你这个并拒绝操作。 shell 允许它,因为它也被 MongoDB 服务器工程师内部用于测试,因此它允许完成各种 weird/unusual 事情。