Mongo触发器:数组全元素匹配表达式的实现方案
解决Mongo Trigger因特定字段更新导致的死循环问题
我配置了Mongo Trigger,当指定集合发生插入/更新操作时,会向AWS EventBridge发送事件。但Worker将数据同步至第三方系统后,会更新集合中的jumpsellerCategoryId字段以及SubCategories数组内的jumpsellerSubCategoryId字段,这会导致触发器被反复触发形成死循环,因此需要排除这两个字段的更新触发。
现有规则的局限
当前使用的规则仅能忽略SubCategories数组第1个元素的更新,无法动态匹配数组内的所有元素——部分集合的SubCategories数组元素多达300个,逐个硬写下标完全不现实。尝试用$替代数组下标,虽然是Mongo合法表达式,但过滤器完全无效。
现有规则代码:
{ "$and": [ { "updateDescription.updatedFields.SubCategories.1.jumpsellerSubCategoryId": { "$exists": false } }, { "updateDescription.updatedFields.jumpsellerCategoryId": { "$exists": false } } ] }
最终解决方案
通过$expr结合Mongo聚合表达式实现动态匹配,核心逻辑:
- 用
$objectToArray将updateDescription.updatedFields转换为键值对数组,方便遍历所有更新字段 - 对
SubCategories数组下任意元素的jumpsellerSubCategoryId字段,用正则匹配字段名格式SubCategories.数字.jumpsellerSubCategoryId,同时校验字段类型为整数 - 对
jumpsellerCategoryId字段做精确匹配,同样校验类型为整数 - 用
$not和$anyElementTrue确保上述两类字段都未被更新时,才触发Trigger
解决方案代码:
{ "$expr": { "$and": [ { "$not": { "$anyElementTrue": { "$map": { "input": { "$cond": { "if": { "$isArray": { "$objectToArray": "$updateDescription.updatedFields" } }, "then": { "$objectToArray": "$updateDescription.updatedFields" }, "else": [] } }, "as": "field", "in": { "$and": [ { "$regexMatch": { "input": "$$field.k", "regex": "^SubCategories\\.\\d+\\.jumpsellerSubCategoryId$" } }, { "$eq": [ { "$type": "$$field.v" }, "int" ] } ] } } } } }, { "$not": { "$anyElementTrue": { "$map": { "input": { "$cond": { "if": { "$isArray": { "$objectToArray": "$updateDescription.updatedFields" } }, "then": { "$objectToArray": "$updateDescription.updatedFields" }, "else": [] } }, "as": "field", "in": { "$and": [ { "$eq": [ "$$field.k", "jumpsellerCategoryId" ] }, { "$eq": [ { "$type": "$$field.v" }, "int" ] } ] } } } } } ] } }
内容的提问来源于stack exchange,提问作者user3569450
相关产品推荐
相关产品推荐

