Puede especificar la validación utilizando operadores del query como $eq y $gt para comparar campos.
Un caso de uso común para la validación de esquemas con operadores del query es cuando deseas crear reglas de validación dinámicas que comparen varios valores de campo en tiempo de ejecución. Por ejemplo, si tienes un campo que depende del valor de otro campo y necesitas asegurarte de que esos valores sean correctamente proporcionales entre sí.
Restricciones
No puedes especificar los siguientes operadores del query en un objeto
validator:No puedes especificar la validación del esquema para:
Colecciones en las bases de datos
admin,localyconfig
Context
Considera una aplicación que rastrea los pedidos de los clientes. Los pedidos tienen un precio base y un IVA. La colección orders contiene estos campos para rastrear el precio total:
priceVATtotalWithVAT
Pasos
El siguiente procedimiento crea una validación de esquema con operadores del query para garantizar que totalWithVAT coincida con la combinación esperada de price y VAT.
Crea una colección con validación.
Crear una colección orders con la validación de esquemas:
db.createCollection( "orders", { validator: { $expr: { $eq: [ "$totalWithVAT", { $multiply: [ "$total", { $sum:[ 1, "$VAT" ] } ] } ] } } } )
Con esta validación, solo puedes introducir documentos si el campo totalWithVAT es igual a total * (1 + VAT).
Confirma que la validación impide documentos no válidos.
La siguiente operación falla porque el campo totalWithVAT no es igual al valor correcto:
db.orders.insertOne( { total: Decimal128("141"), VAT: Decimal128("0.20"), totalWithVAT: Decimal128("169") } )
141 * (1 + 0.20) es igual a 169.2, así que el valor del campo totalWithVAT debe ser 169.2.
La operación devuelve el siguiente 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 } }
Haz que el documento sea válido e insértalo.
Después de actualizar el documento para tener el valor correcto de totalWithVAT la operación tiene éxito:
db.orders.insertOne( { total: Decimal128("141"), VAT: Decimal128("0.20"), totalWithVAT: Decimal128("169.2") } )
MongoDB devuelve la siguiente salida, lo que indica que la inserción fue exitosa:
{ acknowledged: true, insertedId: ObjectId("6304f4651e52f124b84479ba") }
Información Adicional
Puedes combinar la validación del operador del query con la validación de JSON Schema.
Por ejemplo, considere una colección sales con esta validación de esquema:
db.createCollection("sales", { validator: { "$and": [ // Validation with query operators { "$expr": { "$lt": ["$lineItems.discountedPrice", "$lineItems.price"] } }, // Validation with JSON Schema { "$jsonSchema": { "properties": { "items": { "bsonType": "array" } } } } ] } } )
La validación anterior aplica estas reglas para los documentos de la colección sales:
lineItems.discountedPricedebe ser menorlineItems.priceque. Esta regla utiliza el$ltoperador.El
itemscampo debe ser una matriz. Esta regla$jsonSchemautiliza.
Obtén más información
Para ver todos los operadores del query disponibles en MongoDB, consulta Predicados de queries.
Para obtener más información sobre el operador
$expr, que permite el uso de expresiones de agregación dentro del languaje del query, consulta$expr.