mongodb: um banco de dados orientado a documento
Post on 19-May-2015
3.920 Views
Preview:
DESCRIPTION
TRANSCRIPT
/ME
Rails Developer, JobScore (http://www.jobscore.com)
AGENDA
1. Objetivo
2. Histórico
3. Características
4. Relacional versus MongoDB
5. Consultas
6. Map/reduce
7. Operações atômicas
8. Índices
9. Geoposicionamento
10.Por onde continuar?
OBJETIVO
MongoDB busca aproveitar vantagensde armazenamentos de chave-valor
(que, no geral, são rápidos e escaláveis)e banco de dados relacionais tradicionais
(que, no geral, oferecem consultas ricas e várias funcionalidades).
(Adaptado do site oficial do MongoDB)
Quando Chuck Norris fala, todos ficam em silêncio. E morrem.
HISTÓRICO
• Produto da 10gen
•Desenvolvimento iniciou em Outubro de 2007
• Primeira versão pública em Fevereiro de 2009
• Atualmente na versão 1.6
• Licenciado sob a GNU AGPL
CARACTERÍSTICAS (1/2)
• Armazenamento orientado a documentos
• Índices
• Consultas ricas (rich queries)
• Atualizações in-place rápidas
•Map/Reduce
CARACTERÍSTICAS (2/2)
• Replicação e Alta Disponibilidade
• Auto-Sharding
• GridFS
• Suporte Comercial (da 10gen)
RELACIONAL VERSUS MONGODB
TABELA
id nome sobrenome idade
1 Ana Silva 20
2 Maria Carvalho 22
3 João Chaves 21
4 Mário Schimitd 30
... ... ... ...
DOCUMENTO
Id: 1Nome: AnaSobrenome: SilvaIdade: 20
Id: 2Nome: MariaSobrenome: CarvalhoIdade: 22
Id: 3Nome: JoãoSobrenome: ChavesIdade: 21
Id: 4Nome: MárioSobrenome: SchimitdIdade: 30
TERMINOLOGIARelacional Tradicional
(MySQL, PostgreSQL, etc)MongoDB
Database(Banco de dados)
Database(Banco de dados)
Table(Tabela)
Collection(Coleção)
Row(Linha, registro)
Document(Documento)
Column(Coluna)
Attribute(Atributo)
MODELO ENTIDADE-RELACIONAMENTO
MYSQL
artigos comentarios
palavras_chave
artigos_palavras_chave
MODELO ENTIDADEMONGODB
artigos
comentarios
palavras_chave
DOCUMENTO EM MONGODB{
"_id" : ObjectID("4c03e856e258c2701930c091"), "titulo" : "Campus Party Brasil 2011 vêm aí", "atalho" : "campus-party-brasil-2011-vem-ai", "texto" : "A Campus Party Brasil 2011 está chegando, e com elas diversas atrações!", "publicado" : true, "criado_em" : "Mon Oct 4 2010 16:00:00 GMT-0300 (BRT)", "atualizado_em" : "Mon Oct 4 2010 16:00:00 GMT-0300 (BRT)", "comentarios" : [ { "autor" : "Julio", "email" : "julio@monteiro.eti.br", "conteudo" : "Gostei muito da Campus!", "criado_em" : "Mon Oct 4 2010 17:00:00 GMT-0300 (BRT)" } ], "palavras_chave" : [ "cpbr4", "campus", "party" ]}
JSONJavaScript Object Notation
JSONJavaScript Object NotationBinary
B
CONSULTAS
COMO BUSCO...
• ... por uma palavra inteira?db.artigos.find({"titulo" : "campus"})
• ... por parte de uma palavra?db.artigos.find({"titulo" : /campus/i})
• ... por uma palavra dentro de um array?db.artigos.find({"palavras_chave" : "campus"})
• ... por uma palavra dentro de um embutido?db.artigos.find({ "comentarios.email" : "julio@monteiro.eti.br" })
COMO ATUALIZO...
... determinado atributo de um registro?db.artigos.update( { "comentarios.email" : "julio@monteiro.eti.br" }, { $set: { "comentarios.$.email" : "julio@awegen.com" } })
$SET ?
$gt$gte$lt$lte$ne$in$nin$mod
$all$size$exists$type$elemMatch$not$where
OPERADORES
USANDO OPERADORES
•Maior que ($gt):terceiraIdade = db.pessoas.find({ "age": { $gt: 75 } })
• Incluindo ($in):interessante = db.artigos.find({ "tags" : { $in : ["mongodb", "interessante"] } })
•Não incluindo ($nin):todo = db.tarefas.find({ "status" : { $nin : [ "em execucao", "terminado" ] } })
FUNÇÕES ARBITRÁRIAS
• Usando funções arbitrárias (com $where):db.artigos.find({ $where : function() { return this.acessos % 2 == 0} })
• Usando agrupamento (com $group):db.artigos.group({ "key" : { "hits" : true }, "initial" : { "count": 0 }, "reduce" : function(obj, prev) { prev.count++; }})
FUNÇÃO DE AGRUPAMENTO
•Dado que possui documentos como...{ domain: "www.mongodb.org", invoked_at: {d:"2009-11-03", t:"17:14:05"}, response_time: 0.05, http_action: "GET /display/DOCS/Aggregation"}
FUNÇÃO DE AGRUPAMENTO
• Agrupamento:db.test.group( { cond: {"invoked_at.d": {$gte: "2009-11", $lt: "2009-12"}} , key: {http_action: true} , initial: {count: 0, total_time:0} , reduce: function(doc, out){ out.count++; out.total_time+=doc.response_time } , finalize: function(out){ out.avg_time = out.total_time / out.count }} )
FUNÇÃO DE AGRUPAMENTO
• Retorno do agrupamento:[ { "http_action" : "GET /display/DOCS/Aggregation", "count" : 1, "total_time" : 0.05, "avg_time" : 0.05 }]
MAP/REDUCE
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
4
3
7
4
BANCO DE DADOS
db.items.insert({tags: ['dog', 'cat']})
db.items.insert({tags: ['dog']})
db.items.insert({tags: ['dog', 'mouse']})
db.items.insert({tags: ['dog', 'mouse', 'hippo']})
db.items.insert({tags: ['dog', 'mouse', 'hippo']})
db.items.insert({tags: ['dog', 'hippo']})
MAP
var map = function() {
this.tags.forEach(function(t) {
emit(t, {count: 1})
})
}
REDUCE
var reduce = function(key, val) {
var count = 0;
for(var i = 0, len = val.length; i < len; i++) {
count += val[i].count
}
return { count: count };
}
EXECUTANDO
var result = db.items.mapReduce(map, reduce);
RESULTADO
{
"result" : "tmp.mr.mapreduce_1286209644_2", "timeMillis" : 30,
"counts" : {
"input" : 6,
"emit" : 13,
"output" : 4 },
"ok" : 1,
}
RESULTADO (MESMO!)
db["tmp.mr.mapreduce_1286209644_2"].find()
db[result['result']].find()
MAP/REDUCE
{ "_id" : "cat", "value" : { "count" : 1 } }
{ "_id" : "dog", "value" : { "count" : 6 } }
{ "_id" : "hippo", "value" : { "count" : 3 } }
{ "_id" : "mouse", "value" : { "count" : 3 } }
OPERAÇÕES ATÔMICAS
OPERAÇÕES ATÔMICAS
• Incrementando com $incdb.artigos.update( { _id : new ObjectId("4c041...")}, { $inc: {"hits": 1} })
• Atualizando:db.posts.update({}, { $set : { "hits" : 0 }})
ÍNDICES
ÍNDICES
•Desempenho lento para escrita, mas muito mais rápida para leitura
• Para melhores resultados, crie índices por onde você busca
•MongoDB mantém índices em memória
SEM ÍNDICE
db.items.find({tags: "dog"}).explain();
{
"cursor" : "BasicCursor",
"nscanned" : 6,
"nscannedObjects" : 6,
"n" : 6,
"millis" : 10,
"indexBounds" : {
}
}
APLICANDO O ÍNDICE
db.items.ensureIndex({tags: 1})
COM ÍNDICEdb.items.find({tags: "dog"}).explain();{
"cursor" : "BtreeCursor tags_1", "nscanned" : 6, "nscannedObjects" : 6,
"n" : 6, "millis" : 0,
"indexBounds" : { "tags" : [ [
"dog", "dog"
] ] }
}
GEOPOSICIONAMENTO
GEOPOSICIONAMENTO
• Geoposicionamento, com MongoDB, é estupidamente simples
• Apenas adicione um índice:db.lugares.ensureIndex({ localizacao: "2d" })
LUGARES MAIS PERTO
db.lugares.find({
localizacao: { $near : [
21.123456789, -20.123456789
]}
})
20 LUGARES MAIS PERTO
db.lugares.find({
localizacao: { $near : [
21.123456789, -20.123456789
]}
}).limit(20)
EM UMA ÁREA
EM UMA ÁREA
db.lugares.find({
localizacao: { $within: { $box: {
[
[21.123456789, -20.123456789],
[22.123456789, -21.123456789]
]
}}}
})
POR ONDE CONTINUAR?
MONGODBTHE DEFINITIVE GUIDE
REFERÊNCIAS
REFERÊNCIAS
OBRIGADO!
Júlio Monteirojulio@monteiro.eti.br
top related