Puede especificar la validación utilizando operadores de consulta 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 se pueden especificar los siguientes operadores de consulta en un
validatorobjeto: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 } }
Hacer válido el documento e insertarlo.
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 menor quelineItems.price. Esta regla se especifica utilizando el operador$lt.El campo
itemsdebe ser un arreglo. Esta regla se especifica usando$jsonSchema.
Obtén más información
Para ver todos los operadores de consulta disponibles en MongoDB, consulte Selectores de consultas.
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.