Validação de esquema
Nesta página
Novo na versão 3.2.
O MongoDB fornece o recurso de realizar validação de esquema durante atualizações e inserções.
Você pode implementar a validação de esquema na IU para implantações hospedadas no MongoDB Atlas.
Especificar regras de validação
As regras de validação são por collection.
Para especificar regras de validação ao criar uma nova collection, use db.createCollection()
com a opção validator
.
Para adicionar validação de documento a uma collection existente, use o comando collMod
com a opção validator
.
O MongoDB também fornece as seguintes opções relacionadas:
validationLevel
opção, que determina o quão estritamente o MongoDB aplica as regras de validação aos documentos existentes durante uma atualização.validationAction
opção, que determina se o MongoDB deveerror
e rejeitar documentos que violem as regras de validação ouwarn
sobre as violações no registro, mas permitir documentos inválidos.
JSON schema
Novidade na versão 3.6.
A partir da versão 3.6, O MongoDB suporta validação de JSON schema. Para especificar a validação do JSON schema, use o operador $jsonSchema
em sua expressão validator
.
Observação
O JSON schema é o meio recomendado de realizar a validação de esquema.
Por exemplo, o seguinte exemplo especifica regras de validação utilizando JSON schema:
db.createCollection("students", { validator: { $jsonSchema: { bsonType: "object", required: [ "name", "year", "major", "address" ], properties: { name: { bsonType: "string", description: "must be a string and is required" }, year: { bsonType: "int", minimum: 2017, maximum: 3017, description: "must be an integer in [ 2017, 3017 ] and is required" }, major: { enum: [ "Math", "English", "Computer Science", "History", null ], description: "can only be one of the enum values and is required" }, gpa: { bsonType: [ "double" ], description: "must be a double if the field exists" }, address: { bsonType: "object", required: [ "city" ], properties: { street: { bsonType: "string", description: "must be a string if the field exists" }, city: { bsonType: "string", description: "must be a string and is required" } } } } } } })
Para mais informações, consulte $jsonSchema
.
bsonType
definições podem ser encontradas na página de BSON types .
Outras expressões de query
Além da validação do JSON schema que usa o operador de query $jsonSchema
, o MongoDB suporta validação com outros operadores de query, com exceção de:
Por exemplo, o exemplo a seguir especifica regras de validação usando a expressão de query:
db.createCollection( "contacts", { validator: { $or: [ { phone: { $type: "string" } }, { email: { $regex: /@mongodb\.com$/ } }, { status: { $in: [ "Unknown", "Incomplete" ] } } ] } } )
Comportamento
A validação ocorre durante atualizações e inserções. Quando você adiciona validação a uma collection, os documentos existentes não passam por verificações de validação até a modificação.
Para executar verificações de validação em documentos existentes, use o comando validate
ou o auxiliar de shell db.collection.validate()
.
Documentos existentes
A opção validationLevel
determina em quais operações o MongoDB aplica as regras de validação:
Se o
validationLevel
forstrict
(o padrão), o MongoDB aplicará regras de validação a todas as inserções e atualizações.Se o
validationLevel
formoderate
, o MongoDB aplicará regras de validação às inserções e atualizações dos documentos existentes que já atendem aos critérios de validação. Com o nívelmoderate
, as atualizações de documentos existentes que não atendem aos critérios de validação não são verificadas quanto à validade.
Por exemplo, criar uma coleção contacts
com os seguintes documentos:
db.contacts.insert([ { "_id": 1, "name": "Anne", "phone": "+1 555 123 456", "city": "London", "status": "Complete" }, { "_id": 2, "name": "Ivan", "city": "Vancouver" } ])
Emitir o seguinte comando para adicionar um validador à coleção contacts
:
db.runCommand( { collMod: "contacts", validator: { $jsonSchema: { bsonType: "object", required: [ "phone", "name" ], properties: { phone: { bsonType: "string", description: "must be a string and is required" }, name: { bsonType: "string", description: "must be a string and is required" } } } }, validationLevel: "moderate" } )
A collection contacts
agora tem um validador com o validationLevel moderate
:
Se você tentasse atualizar o documento com
_id: 1
, o MongoDB aplicaria as novas regras de validação, pois o documento existente corresponde aos critérios.Por outro lado, o MongoDB não aplicará regras de validação a atualizações do documento com
_id: 2
, pois ele não atende às regras de validação.
A partir da versão 5.0 do MongoDB, o validador retorna informações de erro detalhadas quando uma condição de validação não é atendida. A saída de erro é exaustiva - todos os erros são relatados, não apenas o primeiro.
Importante
A saída de erro destina-se ao consumo humano. Pode mudar no futuro e não deve ser invocado em scripts.
No próximo exemplo, nenhuma das atualizações é consistente com a regra de validação que criamos acima, que exige que name
seja uma string.
db.contacts.update( { _id: 1 }, { $set: { name: 10 } } ) db.contacts.update( { _id: 2 }, { $set: { name: 20 } } )
A saída abaixo mostra que o documento com _id: 1
falha na validação com uma explicação detalhada, conforme mostrado no objeto errInfo
. A atualização para o documento com _id: 2
é bem-sucedida, pois esse documento não atendeu aos critérios iniciais quando a validação foi adicionada.
// _id: 1 WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 121, "errmsg" : "Document failed validation", "errInfo" : { "failingDocumentId" : 1, "details" : { "operatorName" : "$jsonSchema", "schemaRulesNotSatisfied" : [ { "operatorName" : "properties", "propertiesNotSatisfied" : [ { "propertyName" : "name", "details" : [ { "operatorName" : "bsonType", "specifiedAs" : { "bsonType" : "string" }, "reason" : "type did not match", "consideredValue" : 10, "consideredType" : "double" } ] } ] } ] } } } }) // _id: 2 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Para desabilitar totalmente a validação, você pode definir validationLevel
como off
.
Aceitar ou Rejeitar documentos inválidos
A opção validationAction
determina como o MongoDB lida com documentos que violam as regras de validação:
Se o
validationAction
forerror
(o padrão), o MongoDB rejeitará qualquer inserção ou atualização que viole os critérios de validação.Se o
validationAction
forwarn
, o MongoDB registrará quaisquer violações, mas permitirá que a inserção ou atualização continue.
Por exemplo, crie uma collection do contacts2
com o seguinte validador de JSON schema:
db.createCollection( "contacts2", { validator: { $jsonSchema: { bsonType: "object", required: [ "phone" ], properties: { phone: { bsonType: "string", description: "must be a string and is required" }, email: { bsonType : "string", pattern : "@mongodb\.com$", description: "must be a string and match the regular expression pattern" }, status: { enum: [ "Unknown", "Incomplete" ], description: "can only be one of the enum values" } } } }, validationAction: "warn" } )
Com o warn
validationAction
, o MongoDB registra quaisquer violações, mas permite que a inserção ou atualização continue.
Por exemplo, a seguinte operação de inserção viola a regra de validação:
db.contacts2.insertOne( { name: "Amanda", status: "Updated" } )
No entanto, como validationAction
é apenas warn
, o MongoDB registra apenas a mensagem de violação de validação e permite que a operação continue. Execute o seguinte comando para visualizar os registros do MongoDB:
db.adminCommand( { getLog: "global" } )
Dependendo do uso da collection, este comando pode retornar muitos dados. O erro de validação (uma linha longa no registro, reformatado aqui para legibilidade) contém informações como esta:
"{\"t\":{\"$date\":\"2021-01-20T15:59:57.305+00:00\"}, \"s\":\"W\", \"c\":\"STORAGE\", \"id\":20294, \"ctx\":\"conn1\", \"msg\":\"Document would fail validation\", \"attr\":{\"namespace\":\"test.contacts2\", \"document\":{\"_id\":{\"$oid\":\"6008537d42e0d23385568881\"}, \"name\":\"Amanda\", \"status\":\"Updated\"}, \"errInfo\":{\"failingDocumentId\":{\"$oid\":\"6008537d42e0d23385568881\"}, \"details\":{\"operatorName\":\"$jsonSchema\", \"schemaRulesNotSatisfied\":[ {\"operatorName\":\"properties\", \"propertiesNotSatisfied\":[ {\"propertyName\":\"status\", \"details\":[ {\"operatorName\":\"enum\", \"specifiedAs\":{\"enum\":[ \"Unknown\", \"Incomplete\"]}, \"reason\":\"value was not found in enum\", \"consideredValue\":\"Updated\"}]}]}, {\"operatorName\":\"required\", \"specifiedAs\":{\"required\":[\"phone\"]}, \"missingProperties\":[\"phone\"]}]}}}}"
Restrições
Você não pode especificar um validador para collections nos bancos de dados admin
, local
e config
.
Você não pode especificar um validador para collections system.*
.
bypassDocumentValidation
Os usuários podem ignorar a validação do documento usando a opção bypassDocumentValidation
.
Os seguintes comandos podem ignorar a validação por operação utilizando a nova opção bypassDocumentValidation
:
applyOps
comandoComando
findAndModify
e métododb.collection.findAndModify()
Comando
mapReduce
e métododb.collection.mapReduce()
insert
comandoupdate
comando$out
e$merge
estágios para o comandoaggregate
e o métododb.collection.aggregate()
Para sistemas que habilitaram o controle de acesso, para ignorar a validação do documento, o usuário autenticado deve ter a açãobypassDocumentValidation
. Os papéis embutidos dbAdmin
e restore
fornecem esta ação.