MongoDB变更流:如何过滤不含buyer字段的更新通知
问题:MongoDB变更流过滤buyer字段及子字段的更新通知
文档示例
{ id: 139234234, count: 12, type: "apple", buyer: [ {name: "peter", price: 1.23, max: 129}, {name: "alex", price: 1.4, "max": 12146} ] }
常见更新操作
针对buyer字段的更新示例:
db.updateMany({ id: 139234234 }, [ { $set: { buyer: { $concatArrays: [ { $filter: { input: "$buyer", cond: { $ne: ["$$this.name", "john"] } } }, [ { name: "john", price: 12, max: 234 } ] ] } } } ]);
需求与问题
需要配置MongoDB变更流管道,过滤掉所有涉及buyer字段(包括其子字段,如buyer.2.name这类路径)的更新通知。
之前尝试的管道仅能过滤更新字段精确为buyer的情况,无法处理子字段更新:
db.collection.watch([ { $match: { operationType: "update", "updateDescription.updatedFields.buyer": { $exists: false } } } ])
正确的变更流管道
使用$objectToArray将updatedFields转换为键值对数组,再通过$anyElementTrue检查是否存在以buyer开头的字段路径,最后取反过滤掉这些更新:
db.collection.watch([ { $match: { operationType: "update", $expr: { $not: { $anyElementTrue: { $map: { input: { $objectToArray: "$updateDescription.updatedFields" }, as: "field", in: { $or: [ { $eq: ["$$field.k", "buyer"] }, { $regexMatch: { input: "$$field.k", regex: "^buyer\\." } } ] } } } } } } } ])
原理说明
$objectToArray: "$updateDescription.updatedFields":把更新字段的键值对对象转为数组,每个元素包含k(字段名)和v(字段值)。$map:遍历这个数组,对每个字段名检查两种情况:- 字段名精确等于
buyer - 字段名以
buyer.开头(匹配子字段路径)
- 字段名精确等于
$anyElementTrue:判断是否存在符合上述条件的字段。$not:取反结果,仅保留不涉及buyer字段及子字段的更新通知。
内容的提问来源于stack exchange,提问作者TungTung
相关产品推荐
相关产品推荐

