Você pode especificar validação utilizando operadores de query como $eq e $gt para comparar campos.
Um caso de uso comum para validação de esquema com operador de consulta é quando você deseja criar regras de validação dinâmica que comparam vários valores de campo em tempo de execução. Por exemplo, se você tiver um campo que depende do valor de outro campo e precisar garantir que esses valores sejam corretamente proporcionais entre si.
Restrições
Você não pode especificar os seguintes operadores de consulta em um objeto
validator:Você não pode especificar a validação de esquema para:
Coleções nos bancos de dados
admin,localeconfig
Contexto
Considere um aplicativo que rastreia pedidos de clientes. Os pedidos têm um preço base e um deIVA. A collection orders contém estes campo para acompanhar o preço total:
priceVATtotalWithVAT
Passos
O procedimento a seguir cria uma validação de esquema com operadores de query para garantir que totalWithVAT corresponda à combinação esperada de price e VAT.
Crie uma coleta com validação.
Crie uma coleção orders com validação de esquema:
db.createCollection( "orders", { validator: { $expr: { $eq: [ "$totalWithVAT", { $multiply: [ "$total", { $sum:[ 1, "$VAT" ] } ] } ] } } } )
Com essa validação, você só poderá inserir documentos se o campo totalWithVAT for igual a total * (1 + VAT).
Confirme se a validação impede documentos inválidos.
A operação a seguir falha porque o campo totalWithVAT não é igual ao valor correto:
db.orders.insertOne( { total: Decimal128("141"), VAT: Decimal128("0.20"), totalWithVAT: Decimal128("169") } )
141 * (1 + 0.20) é igual a 169.2, portanto, o valor do campo totalWithVAT deve ser 169.2.
A operação retorna este erro:
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 } }
Torne o documento válido e o insira.
Depois de atualizar o documento para ter o valor totalWithVAT correto, a operação será bem-sucedida:
db.orders.insertOne( { total: Decimal128("141"), VAT: Decimal128("0.20"), totalWithVAT: Decimal128("169.2") } )
O MongoDB retorna a seguinte saída, indicando que a inserção foi bem-sucedida:
{ acknowledged: true, insertedId: ObjectId("6304f4651e52f124b84479ba") }
Informações adicionais
Você pode combinar a validação do operador de query com a validação de JSON schema.
Por exemplo, considere uma collection sales com esta validação 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" } } } } ] } } )
A validação anterior força que os documentos na collection sales sigam estas regras:
lineItems.discountedPricedeve ser menor quelineItems.price. Esta regra é especificada utilizando o operador$lt.O campo
itemsdeve ser uma matriz. Esta regra é especificada utilizando$jsonSchema.
Saiba mais
Para ver todos os operadores de query disponíveis no MongoDB, consulte Predicados de query.
Para saber mais sobre o operador
$expr, que permite o uso de expressões de agregação na linguagem de consulta, consulte$expr.