Docs Menu
Docs Home
/
MongoDB 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.

  • You can't specify the following query operators in a validator object:

  • You can't specify schema validation for:

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.

Back

Best Practices