Puede especificar la validación utilizando operadores de consulta como $eqy para comparar $gt campos.
Un caso de uso común para la validación de esquemas con operadores de consulta es cuando se desea crear reglas de validación dinámicas que comparen varios valores de campo en tiempo de ejecución. Por ejemplo, si se tiene un campo que depende del valor de otro campo y se necesita garantizar 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
Considere una aplicación que rastrea los pedidos de los clientes. Los pedidos tienen un precio base y un IVA. La orders colección contiene estos campos para el seguimiento del precio total:
priceVATtotalWithVAT
Pasos
El siguiente procedimiento crea una validación de esquema con operadores de consulta para garantizar que totalWithVAT coincida con la combinación esperada de price y VAT.
Crea una colección con validación.
Cree una colección orders con validación de esquema:
db.createCollection( "orders", { validator: { $expr: { $eq: [ "$totalWithVAT", { $multiply: [ "$total", { $sum:[ 1, "$VAT" ] } ] } ] } } } )
Con esta validación, solo podrá insertar 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, por lo que el valor del campo totalWithVAT debe ser 169.2.
La operación devuelve este 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 que tenga el valor totalWithVAT correcto, la operación se realiza correctamente:
db.orders.insertOne( { total: Decimal128("141"), VAT: Decimal128("0.20"), totalWithVAT: Decimal128("169.2") } )
MongoDB devuelve la siguiente salida, indicando que la inserción fue exitosa:
{ acknowledged: true, insertedId: ObjectId("6304f4651e52f124b84479ba") }
Información Adicional
Puede combinar la validación del operador de consulta con la validación del esquema JSON.
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
$exproperador, que permite el uso de expresiones de agregación dentro del lenguaje de consulta,$exprconsulte.