Você está na página 1de 79

BANCO DE DADOS ORIENTADO A

DOCUMENTOS

Prof.: Ricardo da Silva Torres


rtorres@ic.unicamp.br
www.ic.unicamp.br/~rtorres
INF-0325 Maio de 2019
Objetivos da aula
2

◻ Aprender as principais operações de manipulação


de dados no MongoDB

◻ Estudar exemplos de inserção, consulta, atualização


e exclusão de dados na base
Modelo relacional normalizado
3
Modelo agregado
4

◻ Agregado é uma coleção de objetos relacionados


que queremos tratar como uma unidade
Objeto complexo de dados
Desnormalizado
Modelo agregado
5

Agregado 1
◻ Domain-Driven Design
redundância
Agregado 2

redundância

redundância
Modelo agregado – versão 1
6

Agregado 1
◻ Domain-Driven Design

Agregado 2

A relação entre clientes e pedidos não está em um mesmo agregado


(é uma relação entre agregados)
Modelo agregado – versão 2
7

◻ Pedido agregado com cliente

...
Documento
8

◻ Composto de campo e valores


{
field1: value1,
field2: value2,
field3: value3,
...
fieldN: valueN
}
Documento aninhado
9
Valores dos campos
10

var mydoc = { identificador


_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" }, documento aninhado
birth: new Date('Jun 23, 1912'), data
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}
Tipos de valores
11

◻ Int
◻ Double
◻ String
◻ Array
◻ ObjectId
◻ Boolean
◻ Date
ObjectId
12

◻ Cada documento em uma coleção tem um


identificador único (“chave primária”)
Campo “_id”
Sempre o primeiro do documento
Número auto incrementado
Geração automática usa timestamp
Referência a documento com ObjectId
13
Campos
14

var mydoc = {
_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" },
birth: new Date('Jun 23, 1912'),
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}

_id é reservado
Não pode ter $ ou . ou null
Acesso a vetores
15

◻ “<array>.<index>”

◻ Acesso ao terceiro elemento


"contribs.2"

{
...
contribs: [ "Turing machine", "Turing test", "Turingery" ],
...
}
Acesso a documentos aninhados
16

◻ “<embedded document>.<field>”
Acesso ao sobrenome
■ “name.last”
Acesso ao número do telefone
■ "contact.phone.number"

{
...
name: { first: "Alan", last: "Turing" },
contact: { phone: { type: "cell", number: "111-222-3333" } },
...
}
Selecionando / criando uma base
17

◻ Operação de seleção de base


use myDB
◻ Uma base armazena um conjunto de coleção de
documentos

base
Coleção
1

Coleção
2
Coleção de documentos
18

◻ Uma coleção é um conjunto de documentos


Não requer que tenham o mesmo schema
Comparando terminologias
19

◻ Relacional vs. orientado a documentos


Selecionando / criando uma base
20

◻ Se uma base não existe, quando um documento é


inserido, ela é automaticamente gerada

◻ Exemplo
db.myNewCollection1.insertOne( { x: 1 } )
Operações sobre bases
21

◻ db
Apresenta a base em uso

◻ show dbs
Lista as bases disponíveis
Operações sobre coleções
22

◻ db.createCollection(name, {option1,...,option_n})
db.createCollection(<name>, { capped: <boolean>,
autoIndexId: <boolean>,
size: <number>,
max: <number>,
storageEngine: <document>,
validator: <document>,
validationLevel: <string>,
◻ db.getCollectionInfos() validationAction: <string>,
indexOptionDefaults: <document>,
viewOn: <string>,
pipeline: <pipeline>,
collation: <document> } )
23

Inserção
Inserção de dados
24

◻ Inserção em uma coleção


◻ Atômica no nível de um documento
operador
InsertOne
25

db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"],
size: { h: 28, w: 35.5, uom: "cm" } }
)

documento
resposta

Sucesso
Identificador do documento
da operação
criado
InsertOne especificando o _id
26

◻ db.products.insertOne( { _id: 10, item: "box", qty:


20 } );

◻ _id precisa ser único

◻ Retorno

{ "acknowledged" : true, "insertedId" : 10 }


Exemplo sistema da universidade
27

◻ Cadastro do aluno e suas disciplinas matriculadas

db.universidade.insertOne( {

nome: “João”, matricula: 201822, cpf: “555.666.444-55”,


curso: “ciência da computação”, nascimento: new Date('Jun
23, 1912'),

disciplinas: [
{ nome: “algoritmos”, sala: 72, turma: “E”},
{ nome: “estrutura de dados", sala: 74, turma: “F”}
]

})
InsertMany
28

◻ Inserir múltiplos documentos em uma coleção

db.inventory.insertMany(
[
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom:
"cm" } }
])
29

Consulta
Exemplo produtos em estoque
30

◻ Dados inseridos a serem consultados

db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
Seleciona documentos
31

◻ Todos documentos da coleção


db.inventory.find( {} )

◻ Todos os documentos (identados)


db.inventory.find( {} ).pretty()

SQL correspondente: SELECT * FROM inventory


Usando condição de igualdade
32

◻ Uso da expressão <field>:<value> (filtro)


◻ Exemplo: status = “D”
db.inventory.find( { status: "D" } )

Resposta: documento de retorno

SQL correspondente: SELECT * FROM inventory WHERE status = "D"


Operadores de consulta
33

◻ { <field1>: { <operator1>: <value1> }, ... }

◻ Recupera todos os documentos com status


equivalente a “A” ou “D”
db.inventory.find( { status: { $in: [ "A", "D" ] } } )

SQL correspondente: SELECT * FROM inventory WHERE status in ("A", "D")


Condição AND
34

◻ Filtro com mais de um campo


◻ Recupera documentos com status = “A” AND
quantidade < 30
db.inventory.find( { status: "A", qty: { $lt: 30 } } )

SQL correspondente: SELECT * FROM inventory WHERE status = "A" AND qty < 30
Condição OR
35

◻ Uso do operador OR nas restrições do filtro da


consulta
◻ Recupera documentos em que status = “A” OR
quantidade < 30
db.inventory.find( {
$or: [ { status: "A" }, { qty: { $lt: 30 } } ]
})

SQL correspondente: SELECT * FROM inventory WHERE status = "A" OR qty < 30
Combinando AND e OR
36

◻ Recupera documentos em que o status = “A” AND


quantidade < 30 OR nome do item inicia com “p”
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
})

SQL correspondente:
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")
Ordenação e limite de resultado
37

◻ Ordenação por quantidade (crescente)


db.inventory.find({}).sort({qty:1})

◻ Limite no número de resultados retornados


db.inventory.find({}).sort({qty:1}).limit(10)
Consulta em documentos aninhados
38

◻ Uso de <field>: <value> em que value é o


documento procurado

◻ Recupere documentos em que o campo tamanho


equivale à { h: 14, w:21, uom: "cm" }:
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )

◻ Ordem dos campos precisa ser preservada


Consulta em documentos aninhados
39

◻ Recupera documentos em que o campo uom dentro


do documento tamanho = “in”
db.inventory.find( { "size.uom": "in" } )
Consulta em documentos aninhados
40

◻ Recupera documentos em que o campo uom dentro


do documento tamanho = “in”
db.inventory.find( { "size.uom": "in" } )

◻ Recupere documentos em que o atributo h de


tamanho é < 15
Consulta em documentos aninhados
41

◻ Recupera documentos em que o campo uom dentro


do documento tamanho = “in”
db.inventory.find( { "size.uom": "in" } )

◻ Recupere documentos em que o atributo h de


tamanho é < 15
db.inventory.find( { "size.h": { $lt: 15 } } )
Consulta em documentos aninhados
42

◻ Recupere documentos no campo h < 15, uom = “in”


e status = “D”
Consulta em documentos aninhados
43

◻ Recupere documentos no campo h < 15, uom = “in”


e status = “D”
"size.h": { $lt: 15 }

db.inventory.find( { "size.h": { $lt: 15 },


Consulta em documentos aninhados
44

◻ Recupere documentos no campo h < 15, uom = “in”


e status = “D”
"size.h": { $lt: 15 }
"size.uom": "in",

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in",


Consulta em documentos aninhados
45

◻ Recupere documentos no campo h < 15, uom = “in”


e status = “D”
"size.h": { $lt: 15 }
"size.uom": "in“
status: "D“

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in",


status: "D" } )
Consulta em vetor
46

db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
Procura um elemento no vetor
47

◻ Recupera documentos em que no vetor tags há o


elemento “red”
db.inventory.find( { tags: "red" } )
Procura elementos em um vetor
48

◻ Recupere documentos em que o campo tags


contenha apenas os elementos “red” e “blank”
não importa a ordem

db.inventory.find( { tags: { $all: ["red", "blank"] } } )


Procura um vetor exato
49

◻ Recupere documentos em que o campo tags tem


exatamente dois elementos “red” e “blank”
Exatamente nessa ordem

db.inventory.find( { tags: ["red", "blank"] } )


Procura valor em vetor
50

◻ Recupera documentos com um valor no vetor maior


que algum parâmetro
db.inventory.find( { dim_cm: { $gt: 25 } } )
Combina condições na procura em
51
vetor
◻ O que retorna a seguinte consulta?
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
Combina condições na procura em
52
vetor
◻ O que retorna a seguinte consulta:
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )

◻ Documentos em que elementos no vetor dim_cm


satisfaça o valor >15 e <20
Consulta em vetor de documentos
53

◻ Dados inseridos a serem considerados


db.inventory.insertMany( [
{ item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
{ item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
{ item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
{ item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
Consulta em vetor de documentos
54

◻ Recupera documentos em que um elemento no vetor


instock relaciona-se com um documento (parâmetro)
db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )

◻ Ordem dos campos precisa ser respeitada


db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } )
Consulta em vetor de documentos
55

◻ Recupera documentos em que o vetor instock


contém um documento com campo qty <= 20

db.inventory.find( { 'instock.qty': { $lte: 20 } } )


Consulta em vetor de documentos
56

◻ Uso da posição do vetor

◻ Recupere documentos em que no primeiro elemento


do vetor instock contém um documento com o campo
qty <= 20

db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )


Consulta em vetor de documentos
57

◻ Especificando múltiplas condições


operador $elemMatch

◻ Recupere documentos em que no vetor instock


contém um documento em que as seguintes
condições são satisfeitas (qty = 5 e
warehouse=“A”)

db.inventory.find( {
"instock": { $elemMatch: { qty: 5, warehouse: "A" } }
})
Consulta em vetor de documentos
58

◻ Recupere documentos em que no vetor instock contém


ao menos um documento em que as seguintes
condições são satisfeitas (qty > 10 e <=20)

db.inventory.find({
"instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } }
})
Seleção de campos de retorno
59

db.inventory.insertMany( [
{ item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }},
{ item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }},
{ item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }},
{ item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }},
{ item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }}
]);
Seleção de campos de retorno
60

◻ db.inventory.find({<consulta>}, {campos_retorno})

◻ db.inventory.find( { status: "A" } )


Retorna toda a informação do documento
Seleção de campos de retorno
61

◻ db.inventory.find({<consulta>}, {campos_retorno})

◻ db.inventory.find( { status: "A" } )


Retorna toda a informação do documento

◻ db.inventory.find( { status: "A" }, { item: 1, status: 1 } )

SQL correspondente: SELECT _id, item, status from inventory WHERE status = "A"
Seleção de campos de retorno
62

◻ Removendo o campo _id do retorno

db.inventory.find(
{ status: "A" }, { item: 1, status: 1, _id: 0 } )

SQL correspondente: SELECT item, status from inventory WHERE status = "A"
Seleção de campos de retorno
63

◻ Retorna todos campos exceto aqueles não


selecionados
db.inventory.find( { status: "A" }, { status: 0 } )
Seleção de campos de retorno
64

◻ Retorna todos campos exceto aqueles não


selecionados
db.inventory.find( { status: "A" }, { status: 0 } )

◻ Retorna campos específicos em documentos


aninhados
Não retorna o campo uom de dentro do documento size
db.inventory.find(
{ status: "A" },
{ "size.uom": 0 })
Seleção de campos de retorno
65

◻ Retorna todos campos exceto aqueles não


selecionados
db.inventory.find( { status: "A" }, { status: 0 } )

◻ Retorna campos específicos em documentos


aninhados
Não retorna o campo uom de dentro do documento size
db.inventory.find(
{ status: "A" },
{ "size.uom": 0 })
66

Atualização
Atualização de documentos
67

◻ Dados de entrada
db.inventory.insertMany( [
{ item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
{ item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
{ item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }
] );
Atualiza um documento
68

◻ db.collection.updateOne()

db.collection.updateOne(
{<condição>},
{
<update operator>: { <field1>: <value1>, ... },
<update operator>: { <field2>: <value2>, ... },
...
}
)
Atualiza um documento
69

◻ Atualiza o primeiro documento em que item = “paper”

db.inventory.updateOne(
{ item: "paper" }, Cria o campo se ele não existe
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
})
Resultado:
Exemplo sistema da universidade
70

◻ Cadastro do aluno e suas disciplinas matriculadas

db.universidade.insertOne( {nome: “João”, matricula:


201822, cpf: “555.666.444-55”, curso: “ciência da
computação”, nascimento: new Date('Jun 23, 1912'), }
disciplinas: [
{ nome: “algoritmos", sala: “72”, turma: E},
{ nome: “estrutura de dados", sala: “74”, turma: F}
]})
Exemplo sistema da universidade
71

◻ Atualiza o curso do aluno João

db.universidade.updateOne( { nome: “João” },


{$set: { curso: “Engenharia da Computação” }} )
Atualiza múltiplos documentos
72

◻ db.collection.updateMany()

db.inventory.updateMany(
{ "qty": { $lt: 50 } },
{
$set: { "size.uom": "in", status: "P" },
$currentDate: { lastModified: true }
}
)
Substitui um documento
73

◻ Substitui o conteúdo de um documento inteiro exceto


seu _id

◻ db.collection.replaceOne()

db.inventory.replaceOne(
{ item: "paper" },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, {
warehouse: "B", qty: 40 } ] }
Novos dados do documento
)
74

Remoção
Remoção de dados
75

◻ Remove muitos documentos


db.inventory.deleteMany({})
Remoção de dados
76

◻ Remove muitos documentos


db.inventory.deleteMany({})

◻ Remove documentos com base em uma condição


db.inventory.deleteMany({ status : "A" })
Remoção de dados
77

◻ Remove muitos documentos


db.inventory.deleteMany({})

◻ Remove documentos com base em uma condição


db.inventory.deleteMany({ status : "A" })

◻ Remove apenas um documento com base em uma


condição
db.inventory.deleteOne( { status: "D" } )
db.inventory.deleteOne( { _id: ObjectId(“5656566”)})
Síntese da aula
78

◻ Modelo orientado a documentos é versátil para


diversas aplicações de software

◻ Explora modelo de dados agregados mais flexível


e facilita o mapeamento com objetos em memória

◻ Estudamos operações de inserção, consulta,


atualização e remoção de dados
Referências
79

1. https://docs.mongodb.com

2. Pramod J. Sadalage, Martin Fowler. NoSQL


Distilled: A Brief Guide to the Emerging World of
Polyglot Persistence. Pearson Education, Inc,
2013, ISBN 978-0-321-82662-6