使用查询运算符指定验证
您可以使用查询运算符(例如 $eq
和$gt
来比较字段)来指定验证。
使用查询操作符进行模式验证的一个常见使用场景是,您想要创建在运行时比较多个字段值的动态验证规则。例如,如果您有一个字段依赖于另一个字段的值,并且需要确保这些值相互之间的比例正确。
限制
上下文
考虑一个追踪客户订单的应用程序。这些订单具有基本价格和增值税。 orders
collection 包含以下字段来追踪总价格:
price
VAT
totalWithVAT
步骤
以下过程使用查询操作符创建模式验证,以确保 totalWithVAT
与 price
和 VAT
的预期组合匹配。
1
2
确认验证可以防止无效文档。
由于 totalWithVAT
字段不等于正确值,以下操作失败:
db.orders.insertOne( { total: NumberDecimal("141"), VAT: NumberDecimal("0.20"), totalWithVAT: NumberDecimal("169") } )
141 * (1 + 0.20) 等于 169.2,所以 totalWithVAT
字段的值必须为 169.2。
操作返回此错误:
MongoServerError: Document failed validation Additional information: { failingDocumentId: ObjectId("62bcc9b073c105dde9231293"), details: { operatorName: '$expr', specifiedAs: { '$expr': { '$eq': [ '$totalWithVAT', { '$multiply': [ '$total', { '$sum': [ 1, '$VAT' ] } ] } ] } }, reason: 'expression did not match', expressionResult: false } }
更多信息
您可以将查询操作符验证与 JSON schema 验证结合起来。
例如,考虑具有以下模式验证的sales
集合:
db.createCollection("sales", { validator: { "$and": [ // Validation with query operators { "$expr": { "$lt": ["$lineItems.discountedPrice", "$lineItems.price"] } }, // Validation with JSON Schema { "$jsonSchema": { "properties": { "items": { "bsonType": "array" } } } } ] } } )
前面的验证对 sales
集合中的文档强制执行以下这些规则:
lineItems.discountedPrice
必须小于lineItems.price
。该规则使用$lt
操作符指定。items
字段必须是数组。该规则使用$jsonSchema
指定。