文档菜单
文档首页
/
MongoDB 手册
/ /

使用查询运算符指定验证

本页内容

  • 限制
  • 上下文
  • 步骤
  • 附加信息
  • 了解更多

您可以使用查询运算符指定验证,例如$eq$gt 来比较字段。

使用查询运算符进行模式验证的常见用例是,您希望在运行时比较多个字段值以创建动态验证规则。例如,如果您有一个依赖于另一个字段值的字段,并且需要确保这些值之间比例正确。

考虑一个跟踪客户订单的应用程序。订单有一个基础价格和一个增值税。订单集合包含以下字段以跟踪总价

  • 价格

  • 增值税

  • 含增值税总价

以下过程使用查询操作符创建一个模式验证,以确保 含增值税总价 与预期的 价格增值税 组合相匹配。

1

创建具有模式验证的 orders 集合

db.createCollection( "orders",
{
validator: {
$expr:
{
$eq: [
"$totalWithVAT",
{ $multiply: [ "$total", { $sum:[ 1, "$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
}
}
3

更新文档以包含正确的 totalWithVAT 值后,操作成功

db.orders.insertOne( {
total: NumberDecimal("141"),
VAT: NumberDecimal("0.20"),
totalWithVAT: NumberDecimal("169.2")
} )

MongoDB 返回以下输出,表示插入成功

{
acknowledged: true,
insertedId: ObjectId("6304f4651e52f124b84479ba")
}

您可以将查询运算符验证与 JSON Schema 验证 结合使用。

例如,考虑一个具有以下模式验证的 销售 集合

db.createCollection("sales", {
validator: {
"$and": [
// Validation with query operators
{
"$expr": {
"$lt": ["$lineItems.discountedPrice", "$lineItems.price"]
}
},
// Validation with JSON Schema
{
"$jsonSchema": {
"properties": {
"items": { "bsonType": "array" }
}
}
}
]
}
}
)

前面的验证强制实施以下规则,用于 销售 集合中的文档

  • lineItems.discountedPrice 必须小于 lineItems.price。此规则使用 $lt 操作符指定。

  • items 字段必须是一个数组。此规则使用 $jsonSchema.

  • 要查看 MongoDB 中所有可用的查询操作符,请参阅 查询选择器。

  • 有关 $expr 操作符的更多信息,该操作符允许在查询语言中使用聚合表达式,请参阅 $expr.

返回

最佳实践