Workshop MongoDB

Post on 12-Apr-2017

269 views 6 download

Transcript of Workshop MongoDB

Armazenamento e consultas em grande volume de dados com flexibilidade e performance.

Objetivo: Uma visão geral sobre funcionalidades, particularidades e

performance.

Leonardo Loures Quirino

Desenvolvedor Java na Bematech desde 2014.

leonardo.quirino@bematech.com.br

twitter: @LeonrdQrn

Tópicos

Introdução ao MongoDBManipulação de dadosPerformanceRéplicasShardingFramework de AgregaçãoFrameworks Java

Introdução ao MongoDB

Banco de dados não relacional

Orientado a documentos

Schema flexível

Open Source

Introdução ao MongoDB

Documentos word??? Não!

Documentos JSONEx:

{ “a” : 6,"b” : “teste”,“frutas” : [“maçã”, “uva”]

}

Introdução ao MongoDB

Flexibilidade:

Requisitos

Soluções incrementais

Melhorias e evoluções

Performance horizontalmente escalável

Sem suporte a joins

Sem suporte a transações

Performance x funcionalidade

Introdução ao MongoDB

Relacional MongoDatabase Database

tabela coleçõesíndice índicelinha documento

coluna campojoin agrupamento & ligações

Introdução ao MongoDB

Exemplos de utilização

● ticketmaster ● EA ● SquareEnix● Google ● Cisco ● ebay● facebook ● Foursquar

e

Manipulação de dados

BSON - Binary JSON

Superset de JSON

Saiba mais: http://bsonspec.org/

Manipulação de dados

CRUD:

Insert

Find

Remove

Update

Inserindo um documento

> doc = {“nome” : “Leonardo Quirino”,“idade” : “30”,

profissão” : “Desenvolvedor”}

> db.pessoas.insert ( doc )

Procurando documentos

> db.pessoas.findOne( ) ou db.pessoas.find( )

{ “_id” : ObjectId("507f1f77bcf86cd799439011"), “nome” : ”Leonardo Quirino”, “idade” : 30, “profissão” : “Desenvolvedor”

}

Procurando documentos

O campo _id

Análogo à chave primária no modelo relacional

Campo obrigatório

Valor único dentro da coleção

Valor imutávelPode ser um documento

Ex:“_id” : { “nome” : Fulano, “sobrenome” : “de tal” }

Procurando documentos

Os métodos de busca aceitam parâmetros para realizar as buscas.Primeiro argumento : FiltrosSegundo argumento : Modelo a ser retornado> db.pessoas.findOne( { “nome” : “Leonardo Quirino” } , { “nome” : true } )

{ “_id” : ObjectId("....") , “nome” : ”Leonardo Quirino” }

> db.pessoas.findOne( { “nome” : “Leonardo Quirino” } , { “nome” : true , “_id” : false } )

{ “nome” : ”Leonardo Quirino” }

Procurando documentos

Operadores$gt e $lt / $gte e $lte

Ex: > db.notas.find({“nota” : {$gt : 60 }})

$existsEx: > db.pessoas.find({“profissão” : {$exists : true }})

$typeEx: > db.pessoas.find({“nome” : {$type : 2 }})

https://docs.mongodb.org/manual/reference/bson-types/

$regexEx: > db.pessoas.find({“nome” : {$regex : “o$” }})

Operadores$or

Ex: > db.pessoas.find ({ $or : [{ “nome" : “Leonardo Quirino” },{ “profissão” : “Desenvolvedor” }

] } )

$andEx: > db.pessoas.find ({ $and : [

{ “nome" : “Leonardo Quirino” },{ “profissão” : “Desenvolvedor” }

] } )

Procurando documentos

> db.notas.find ( {“nota” : { $gt : 50 },“nota” : { $lt : 60 }

} );

[ ] Encontra todos os documentos com nota entre 50 e 60[ ] Encontra todos os documentos com nota maior que 50[ ] Encontra todos os documentos com nota menor que 60[ ] Nenhuma das opções

Pergunta

X

Queries em arrays

Se quisermos buscar valores dentro de arrays?

{ “_id” : ObjectId("507f1f77bcf86cd799439011"), “nome” : ”Leonardo Quirino”, “idade” : 30, “skills” : [ “Java”, “MongoDB”]}

> db.pessoas.find ({ “skills” : “MongoDB” })

Queries em arrays

$elemMatch

{ _id: 1, resultados: [ 82, 85, 88 ] }{ _id: 2, resultados: [ 75, 88, 89 ] }

> db.resultados.find ({ results : { $elemMatch: { $gte: 80, $lt: 85 } } }){ "_id" : 1, "results" : [ 82, 85, 88 ] }

Operações de conjunto

$all> db.pessoas.find ( { “skills” : { $all : [“java”, “mongodb”] } )

$in> db.pessoas.find ( { “skills” : { $in : [“java”, “mongodb”] } )

Documentos aninhados

Ex: > db.usuarios.find({ “email” : {

“pessoal” : “ful@no.com.br”, “trabalho” : “fulano@bematotvs.com.br” }})

Notação de ponto

> db.usuarios.find ({“email.trabalho” : “fulano@bematotvs.com.br”})

Documentos aninhados

Ex: { product : "Super phone",price : 100.000,reviews : [

{ user : "fred", comment : "Great!" , rating : 5 },{ user : "tom" , comment : "I agree with Fred,

somewhat!" , rating : 4 }]

}

Encontrar produtos que custem mais de 10.000 e possuem rating 5 ou mais.

> db.catalogo.find ({“pricing” : { $gte : 10.000 },“reviews.rating” : { $gte : 5 }

})

Objeto Cursor

> cur = db.catalogo.find({“pricing” : { $gte : 10.000},“reviews.rating” : { $gte : 5}

})

Ex:cur.hasNext();cur.next();cur.sort({“princing” : 1});

Contando documentos

count( )Estrutura similar ao find( ).

Ex: > db.catalogo.count({

“pricing” : { $gte : 10.000},“reviews.rating” : { $gte : 5}

})

Atualizando documentos

Se eu quisesse adicionar um endereço no meu cadastro?> db.pessoas.update(

{“nome” : ”Leonardo Quirino”},{“nome” : “Leonardo Loures Quirino”, “Endereço” :

“Jacarepaguá”})

Problema?

O documento passado como segundo argumento substitui o documento original como um todo!

Atualizando documentos

Operadores de atualização$set

> db.pessoas.update({“nome” : ”Leonardo Quirino”},

{$set : { “Endereço” : “Jacarepaguá”}})

$inc> db.pessoas.update({“nome” : ”Leonardo Quirino”},

{$inc : { “Idade” : 1 }})

$mul, $rename, $min, $max….

Atualizando documentos

Operadores de arrays$push & $addToSet

db.arrays.update( {“_id” : 10} , { $push : { “a” : 0 } } )db.arrays.update( {“_id” : 10} , { $push : { “a” : { $each : [ 0 ,

1 , 5 ] } } } )

$popdb.arrays.update( {“_id” : 10} , { $pop : { “a” : 1 } } )

$pulldb.arrays.update( {“_id” : 10} , { $pull : { “a” : 50 } } )

$pullAlldb.arrays.update( {“_id” : 10} , { $pullAll : { “a” : [ 0 , 5 ] } } )

Atualizando documentos

Upsert> db.teste.update ( { username : 'fulano' }, { '$set' : { 'interests': [ “FIFA” , “Ps4” ] } } , { upsert : true } );

Multi Update> db.empregados.update(

{ }, { '$set' : { “grupo”: “Totvs” } } , { multi : true } );

Removendo documentos

remove( )Estrutura similar ao find( ).

Ex: > db.catalogo.remove( {

“pricing” : { $gte : 10.000},} )

> db.pessoas.remove( { } );> db.pessoas.drop( { } );

Performance

Modelagem de schemas

Índices

Bancos relacionaisBasicamente focar na 3FN

MongoDBQual schema que os documentos devem seguir ?Quais dados serão mais lidos x dados mais escritos?E mais importante, como atender a sua aplicação de forma

específica?

Se você trabalhar com sua base do mesmo jeito que faria com um banco relacional, você muito provavelmente não vai estar fazendo da melhor forma.

Schemas flexíveis

Modelando schemas

Frequência de acesso dos dados? Leitura de Documentos aninhados é muito rápida

Garantir consistência na relação entre documentos?Aproveitar operações atômicas

Qual estrutura tende a crescer/ser modificada?Evitar explosão de dados em arrays

Tamanho máximo de um documento = 16 MB

Uma estrutura de dados ordenada que armazena referências aos dados do banco.Aumenta muito a performance da leituraPode diminuir a performance de escritaOcupa espaço no armazenamentoÍndice obrigatório em _id

Índices

Índices

Tipos de Índices

Índice simples ( individual ou composto )Arrays (índice multikey)Índice únicoÍndice esparsoÍndice TTL (Time To Live)Índice Geoespacial (2D ou esférico)Índice de texto

Como escolher um índice?

Entenda as necessidades da aplicaçãoQuais queries demoram a executar?Quais dados são frequentemente usados?Experimentação!

Como escolher um índice?

Comando explain( )> db.productos.explain().find( { categoria: "games" } )

Retorna dados sobre o planejamento interno e a execução das queriesPasso a passo da buscaBusca por índice ou busca diretaNúmero de índices e documentos lidos e retornados

Réplicas

Redundância de dados em nós de servidores MongoDB

Alta disponibilidade

Redundância de dados

Recuperação de desastres

Conjunto de réplicas

Composto de 1 nó primário e N secundários.

Trabalha com replicação de declaraçõesAssíncrona ( padrão )Síncrona

Contexto com recuperação e configuração automática, comunicação com aplicação de forma transparente.

Permite flexibilidade de acesso com leitura em servidores secundários.

Sharding

Processo de armazenar um conjunto massivo de dados através de um cluster de servidores MongoDB.

Objetivo de evitar que um número grande de requisições de leitura e escrita exaustem os recursos de um servidor.

Sharding

Pode ser, e é recomendado que seja, utilizado em conjunto com conjuntos de Réplicas.A aplicação se comunica de forma transparente com um processo MongoS que distribui as requisições atráves dos shards

Particionamento de dados

Os dados em um shard são particionados em nível de coleção. As coleções selecionadas são particionadas a partir de Shard Keys.A shard key é um dos índices, ou faz parte de um índice composto da coleção, mas cada coleção só pode ter 1 shard key.

Shard keys

A Chave errada pode fazer com que o cluster perca o propósito.

Escolher uma chave com presença praticamente obrigatória.

Evitar chaves que cresçam monotonicamente

Range based ( padrão )

Hash based

Shard keys

Framework de agregação

Operações que processam os dados e retornam resultados computados.

Origem na cláusula Group BY do SQL.

Comandos singularesPipeline de agregaçãoMap Reduce

Comandos singulares

count, distinct e groupEx:

{ a: 1, b: 0 }{ a: 1, b: 1 }{ a: 1, b: 4 }{ a: 2, b: 2 }

> db.colecao.count()4> db.colecao.count( { “a” : 1 } )

3> db.colecao.distinct( “a” )[1 , 2]

Pipeline de agregação

Passos dinâmicos que são executados sequencialmente pelo banco.

Consiste de um array de estágios com as operações desejados.

Grande conjunto de operações à disposição.

Operações e operadores

Operações$match$project $limit$skip$group$sort$unwind

Operações e operadores

OperadoresBooleanos

$and, $or, $notComparação

$eq, $gt, $gte, $lt, $lte, $ne e $cmpConjuntos $setEquals, $setIntersection, $setUnion, $setDifference, $setIsSubset, $anyElementTrue, $allElementsTrue Array

$size

Há também operadores aritméticos, de string, datas, de busca de texto, geoespaciais entre outros

Otimização do pipeline de agregação

O pipeline de agregação tem uma fase interna de otimização que pode transformar a forma ou a ordem das operações a serem executadas.

Ex:Um Sort seguido de Match é executado como um Match seguido de

Sort, pois assim é limitado o num de docs a ser ordenado.2 matches seguidos se tornam 1 matchSkip e limit viram limit e skip.

{ $skip: 10 } , { $limit: 5 } -> { $limit: 15 } , { $skip: 10 }Sort seguido de limit vira uma única fase com um sort limitado

Entre outros…

Otimização do pipeline de agregação

Também temos que otimizar nossas queriesExecutar matches e projects antes de outras operaçõesCuidado ao utilizar Unwind evitando executar seguidamente

Pipeline de agregação tem seus limites

Limites do pipeline de agregação

Entre cada fase da agregação só podem trafegar 100 MB de dadosResultado é um documento, ou seja, possui limite de 16MBAlgumas operações não são otimizadas para shards

Exemplo

Map Reduce

Framework anterior ao Pipeline de agregaçãoPassos fixos, mas com funções Javascript.

Usar somente se a flexibilidade for necessária, não é mais recomendado.

Exemplo

Frameworks Java

Java Driver

Spring Data

Morphia

Jongo

Hibernate

Cursos com certificados de conclusão.Recomendado para quem quiser tentar uma certificação.

Quer saber mais?

https://university.mongodb.com/ https://docs.mongodb.org/manual/

Perguntas?

Obrigado!