mongo.sh-600x600Os bancos não relacionais precisam abrir mão de recursos como integridade referencial para ganhar flexibilidade e outras facilidades inexistentes no modelo relacional. Com isso, para manter a integridade dos dados, o controle costuma ser feito via aplicação, com validações e funções específicas para isso.

Com a versão 3.2 do MongoDB, novos recursos como validação de documentos, verificando se informações inseridas em documentos atendem a critérios pré-estabelecidos, como:

  • Se a chave (campo) existe;
  • Se contém informação no formato certo (string, inteiro, data, bool, etc);
  • Se está em um formato específico (via expressão regular);
  • Se o elemento inserido faz parte de uma lista;

Com isso é possível forçar uma melhor padronização dos documentos e tirando um pouco esse controle da aplicação.

Exemplo: precisamos criar uma base de cadastro apenas dos usuários da região Sul do país. Queremos também que todos os usuários tenham mais de 21 anos e que o celular informado corresponda a uma das 4 principais operadoras de celular. A validação dessa coleção, chamada “cadastro_sul” seria:

db.createCollection( "cadastro_sul", {
   validator: { $and:
      [
         { celular: { $type: "string" } },
         { operadora_celular: { $in: [ "Claro", "Tim", "Oi", "Vivo" ] } },
         { uf: { $in: [ "RS", "SC", "PR" ] } },
         { ano_nascimento: { $lte: 1994} }
      ]
   }
} )

Desta maneira, as chaves mínimas necessárias para um documento nessa coleção são: celular como string, operadora_celular precisa ser ou Claro, Tim, Oi ou Vivo, uf precisa ser ou RS, ou SC ou PR e o ano de nascimento precisa ser menor ou igual que 1994.

Exemplo, o documento abaixo atende todos os requisitos de validação:

> db.cadastro_sul.insert({
... 'nome': 'Christiano',
... 'email': 'xxx@xxx.com',
... 'celular': '(51) 9111-0000',
... 'operadora_celular': 'Claro',
... 'uf': 'RS',
... 'ano_nascimento': 1979})

WriteResult({ "nInserted" : 1 })

Agora vou tentar cadastrar outro usuário e informando que sua operadora é Nextel (que não está na lista de validação):

> db.cadastro_sul.insert({
... 'nome': 'Joaquim',
... 'email': 'joaquim@xxx.com',
... 'celular': '(51) 9111-0000',
... 'operadora_celular': 'Nextel',
... 'uf': 'RS',
... 'ano_nascimento': 1988})

WriteResult({
	"nInserted" : 0,
	"writeError" : {
		"code" : 121,
		"errmsg" : "Document failed validation"
	}
})

Desta maneira, qualquer valor que não atenda os requisitos de validação, o MongoDB (ou driver) retornará um erro e não aceitará esse insert ou update.

Lembrando que esse recurso só está disponível a partir da versão 3.2, no momento em que escrevo esse post, essa versão ainda está em release candidate.

Espero que tenha gostado de mais uma novidade. Se gostou, deixe um comentário e compartilhe nas redes sociais.