Blog Cluster

MongoDB Schema Validation

E aí pessoal, tudo certo? Hoje aqui em Porto Alegre, depois de mais uma semana treinando em MongoDB uma turma de devs. E como um dos assuntos foi a validação de documentos, compartilho com vocês uma visão desse recurso que vem se tornando cada dia mais importante.

Porque validar?

Bom, confesso que a primeira vez que tive notícias sobre o schema validation pensei: meu, pra que delegar isso pra um banco que tem como sua principal característica a performance?

Sim, porque quando pensamos em bancos NoSQL o primeiro que nos vem à cabeça é: vou gravar qualquer coisa, que legal! E realmente na maioria dos projetos iniciados com NoSQL é isso que acontece, porém, a medida em que as aplicações vão crescendo e aumentando o volume dos dados e de acesso, um mínimo de organização é requerido. É aí que entra o Schema Validation!

Validação no MongoDB, isso é novo?

Não. A validação de documentos foi introduzida originalmente na versão 3.2 e evoluiu muito desde então. O que começou timidamente com suporte a alguns poucos operadores, hoje tem um operador exclusivo e bastante robusto!

Agora com a versão 3.6 temos o $jsonSchema que está baseado no draft 4 do JSON Schema.

Quando especificada, a validação ocorrerá a cada insert ou update na coleção criada utilizando a opção validator, que por sua vez terá as regras ou expressões de validação.

Assim como todas as funções que possam afetar a performance do banco, o schema validation pode ser ligado ou desligado a qualquer momento e tem alguns comportamentos para esses casos.

Validation Level e Validation Action

Podemos utilizar o schema validation para uma coleção que já exista e contenha documentos utilizando o comando collMod, como também podemos especificar no momento da criação de uma nova especificando as regras através do opção validator no comando db.createCollection().

validationLevel determina como o MongoDB aplica as regras de validação para documentos existentes durante um update. Já a opção validationActiondetermina se o MongoDB retornará um erro e rejeita os documentos que estão violando as regras de validação ou gravará um warn com essas violações no log e permitirá esses documentos inválidos.

Documentos Existentes

Podemos controlar como o MongoDB gerencia os documentos existentes utilizando a opção validationLevel.

Por default, o validationLevel é strict e o MongoDB aplicará as regras de validação em todos os inserts e updates. Setando o validationLevel para moderate fará com que as regras sejam aplicadas para os inserts e updates e nos documentos existentes que preencham todos os requisitos da validação. Os documentos existentes na coleção e que não atendam essas regras não serão verificados.

Aplicando uma validação simples

Nesse exemplo vou criar uma coleção chamada clientes onde vou requerer os campos documento, nome e cep. Vejamos como fica:

db.createCollection("clientes", {
    validator: {
       $jsonSchema: {
          bsonType: "object",
          required: [ "documento", "nome", "endereco.cep" ],
          properties: {
                "documento":{
                    bsonType: "string",
                    description: "O Documento é um atributo requerido e contém o CPF do cliente",
                    maxLength: 11,
                    minLength: 11,
                },
                "nome":{
                    bsonType: "string",
                    description: "O Nome é um atributo requerido"
                },
                "endereco.cep": {
                    bsonType: "string",
                    description: "O CEP é um atributo requerido",
                    maxLength: 8,
                    minLength: 8
                }
            }
        }
    }
});

Vejamos mais detalhadamente cada uma das opções que especifiquei no validator:

$jsonSchema

Esse é o objeto principal para utilizarmos o schema validation e termos acesso a mais recursos. Dentro dele especificamos o tipo object para o bsonType, em seguida declaramos um array que deverá conter os nomes dos atributos requeridos no documento.

properties

Nesse nível definimos as propriedades da validação para cada atributo, ou melhor, entramos mais a fundo atributo por atributo e vamos além da simples obrigatoriedade do atributo.

Note que para cada atributo colocamos propriedades diferentes, podemos definir o bsonType, dar uma descrição e até definir tamanho mínimo e máximo.

Várias key-words são permitidas nas propriedades e nos permitem uma gama gigantesca de combinações para as validações. Veja mais detalhes dessas key-words aqui

Esses são os atributos mínimos para habilitar a validação em uma coleção.

Aceitando ou Rejeitando Documentos Inválidos

Como disse quem controla esse processo de “ok” ou “não ok” na validação é o validationAction.

Tendo por base o schema definido em nosso exemplo, com o validationActionsetado para error, todos os documentos que não estiverem dentro das regras serão rejeitados e o MongoDB retornará uma mensagem de erro.

Já para a action warn o documento será aceito (inserido ou atualizado), porém, um registro no log será gerado, vejamos um exemplo:

db.clientes.insert( { nome: "Leandro", status: "Atualizado" } )
2017-12-01T12:31:23.738-0500 W STORAGE  [conn1] Document would fail validation collection: testeSchema.clientes doc: { _id: ObjectId('5a2191ebacbbfc2bdc4dcffc'), nome: "Leandro", status: "Atualizado" }

Restrições e Bypass

Não conseguimos especificar uma validação para as coleções dos bancos adminlocalconfig. Tampouco para as coleções system.*

Algumas roles podem têm permissão para dar um bypass no schema validation, são elas: dbAdmin e restore. Em um ambiente com autenticação habilitada um bypass na validação tem que usar a opção bypassDocumentValidation, mas um conselho: não fale dessa opção pra muita gente! Rssss

Conclusão

Bem pessoal, é isso… espero ter ajudado vocês a conhecerem um pouco mais sobre esse recurso que à medida em que nossos dados crescem se faz cada vez mais necessário. Para mais informações acesse a página com a documentação oficial do MongoDB aqui

Até a próxima…

PS: comecei a escrever em Porto Alegre e terminei no Rio de Janeiro! 😉

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *