mongodb: um banco de dados orientado a documento

Post on 19-May-2015

3.920 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Palestra ministrada no dia 18 de janeiro de 2011 (2011-01-18) na Campus Party Brasil 2010, na área de Desenvolvimento, em São Paulo/SP.

TRANSCRIPT

Júlio Monteirojulio@monteiro.eti.br

/ME

Rails Developer, JobScore (http://www.jobscore.com)

/ME

http://julio.monteiro.eti.br

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?

REFERÊNCIAS

REFERÊNCIAS

OBRIGADO!

Júlio Monteirojulio@monteiro.eti.br

top related