Docs Menu

Docs HomeDevelop ApplicationsMongoDB Manual

Specify Validation With Query Operators

On this page

  • Restrictions
  • Context
  • Steps
  • Additional Information
  • Learn More

You can specify validation using query operators such as $eq and $gt to compare fields.

A common use case for schema validation with query operators is when you want to create dynamic validation rules that compare multiple field values at runtime. For example, if you have a field that depends on the value of another field and need to ensure that those values are correctly proportional to each other.

Consider an application that tracks customer orders. The orders have a base price and a VAT. The orders collection contains these fields to track total price:

  • price

  • VAT

  • totalWithVAT

The following procedure creates a schema validation with query operators to ensure that totalWithVAT matches the expected combination of price and VAT.

1

Create an orders collection with schema validation:

db.createCollection( "orders",
{
validator: {
$expr:
{
$eq: [
"$totalWithVAT",
{ $multiply: [ "$total", { $sum:[ 1, "$VAT" ] } ] }
]
}
}
}
)

With this validation, you can only insert documents if the totalWithVAT field equals total * (1 + VAT).

2

The following operation fails because the totalWithVAT field does not equal the correct value:

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

141 * (1 + 0.20) equals 169.2, so the value of the totalWithVAT field must be 169.2.

The operation returns this error:

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

After updating the document to have the correct totalWithVAT value, the operation succeeds:

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

MongoDB returns the following output, indicating that the insert was successful:

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

You can combine query operator validation with JSON Schema validation.

For example, consider a sales collection with this schema validation:

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

The preceding validation enforces these rules for documents in the sales collection:

  • lineItems.discountedPrice must be less than lineItems.price. This rule is specified using the $lt operator.

  • The items field must be an array. This rule is specified using $jsonSchema.

  • To see all query operators available in MongoDB, see Query Selectors.

  • To learn more about the $expr operator, which allows the use of aggregation expressions within the query language, see $expr.

← Tips for JSON Schema Validation