更新子字段时mongodb流发生变化

问题描述 投票:0回答:1

我正在使用 MongoDB 4.4.10 和 pymongo 4.6.0

更新文档的子字段时,即

"configuration.requested_state"
,请执行以下操作:

result = await self._collection.update_one(
    {"_id": ObjectId(my_id)}, {"$set": {"configuration.requested_state": state}}
)

在列出更改时:

pipeline = [
            {
                "$match": {
                    "$or": [
                        {
                            "operationType": "update",
                            "updateDescription.updatedFields.configuration.requested_state": {
                                "$exists": True,
                            },
                        },
                        {"operationType": "insert"},
                    ]
                }
            }
        ]

我没有收到任何更新。事实上,与此更改相关的文档是:

'updateDescription': {'updatedFields': {'configuration.requested_state': 'stopped'}}

很难过滤,因为字段

'configuration.requested_state'
包含一个点。

但是,如果我更新完整的

"configuration"
,而不仅仅是
"configuration.requested_state"
,我会得到预期的更新:

'updateDescription': {'updatedFields': {'configuration' : { 'requested_state': 'stopped'}}}

我的管道过滤器在其上工作。但这是不可接受的,因为这意味着推送整个文档,而我只想更新一个子集。

有没有办法为这次更新构建带有过滤器的管道? (即字段名称中带有点)

mongodb pymongo
1个回答
0
投票

MongoDB 5.0 引入了 $getField 聚合运算符,可以更好地处理非字母数字字符的字段名称。

您可以通过使用 $expr 查询运算符在匹配表达式中使用 $getField。

在下面的变更流管道中,$getField 运算符用于从变更文档中的“updatedFields”字段中获取名为“configuration.requested_state”的字段的值,然后“$gt”将其与 null 进行比较。由于 null(几乎)是 MongoDB 中的最小值比较/排序顺序除“null”和“undefined”之外的任何值都将匹配。

db.collection.watch([
   {$match:{$expr:{
        $gt:[null,
             {$getField: {
                input:"$updatedFields",
                field:"configuration.requested_state"
             }}
        ]
   }}}
])

Mongoplayground.net 不支持变更流,但这里有一个聚合示例,显示该管道可以匹配包含点的字段名: 游乐场

© www.soinside.com 2019 - 2024. All rights reserved.