MongoDB集合架构验证:$elemMatch内$expr的替代方案
MongoDB 查询式架构验证解决方案
要实现你需要的验证规则(若文档存在arr字段,则所有元素需满足「无b字段」或「a > b」),可以利用$expr查询算子结合聚合表达式来实现——$expr属于查询算子范畴,符合架构验证仅支持查询算子的要求,之前的问题是错误地将$expr放在$elemMatch内部,正确的写法是将$expr作为顶层验证条件。
具体验证规则
db.createCollection("your_collection_name", { validator: { $expr: { $or: [ // 情况1:文档不存在arr字段,直接合法 { $not: { $exists: "$arr" } }, // 情况2:arr存在时,所有元素必须满足条件 { $allElementsTrue: { $map: { input: "$arr", as: "elem", in: { $or: [ // 元素不存在b字段 { $not: { $exists: "$$elem.b" } }, // 元素存在b字段且a > b { $gt: [ "$$elem.a", "$$elem.b" ] } ] } } } } ] } }, // 可选:设置验证失败的行为,error=拒绝插入,warn=仅警告 validationAction: "error" })
规则解释
$or分支处理两种合法场景:- 文档没有
arr字段时直接通过验证; - 文档存在
arr字段时,需确保所有元素符合要求。
- 文档没有
$map遍历数组元素:对arr中的每个元素,判断是否满足「无b字段」或「a > b」,返回一个布尔值数组。$allElementsTrue校验数组:检查布尔数组是否全为true,确保arr中没有不符合条件的元素。
验证效果
- 无效文档(如
{_id:1, arr: [{a:5}, {a:3, b:4}]})会因第二个元素a <= b导致$allElementsTrue返回false,被验证规则拒绝; - 以下文档会通过验证:
- 无
arr字段:{_id:2, name: "example"} arr元素均无b字段:{_id:3, arr: [{a:5}, {a:2}]}arr元素均满足a > b:{_id:4, arr: [{a:5, b:3}, {a:6, b:2}]}
- 无
内容的提问来源于stack exchange,提问作者Sebu
相关产品推荐
相关产品推荐

