我正在使用 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 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 不支持变更流,但这里有一个聚合示例,显示该管道可以匹配包含点的字段名: 游乐场