Especificar validação com operadores de query
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
,local
econfig
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:
price
VAT
totalWithVAT
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: NumberDecimal("141"), VAT: NumberDecimal("0.20"), totalWithVAT: NumberDecimal("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: NumberDecimal("141"), VAT: NumberDecimal("0.20"), totalWithVAT: NumberDecimal("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.discountedPrice
deve ser menor quelineItems.price
. Esta regra é especificada utilizando o operador$lt
.O campo
items
deve ser uma matriz. Esta regra é especificada utilizando$jsonSchema
.
Saiba mais
Para ver todos os operadores de query disponíveis no MongoDB, consulte Seletores de consulta.
Para saber mais sobre o operador
$expr
, que permite o uso de expressões de agregação na linguagem de consulta, consulte$expr
.