quarta-feira, 23 de dezembro de 2015
MongoDB - Sharding
Como
forma de manter a alta performance na leitura e escrita de dados,
deve ser adicionado mais máquinas para dividir os dados, isso é o
que chamamos de Sharding.
Isso proporciona um crescimento horizontal.
A
diferença de crescimento horizontal e vertical é que no vertical
ele irá exigir a máquinas cada vez mais potentes para poder atender
a demanda, já a horizontal é vai utilizar várias maquinas para
dividir o processamento. As maquinas utilizadas no crescimento
horizontal não precisam ser de alta performance, ela possibilita o
uso de máquinas de pequeno e médio porte.
O
cluster no MongoDB, possui 3 serviços diferentes:
shards
config
servers
router
Os
shards
que é onde ficam os dados, os config
servers
são os servidores de configuração do servidor e os routers
que são os servidores que recebem as requisições e busca o shard
correto para executar a ação. A aplicação sempre vai se conectar
ao router,
que usará os metadados que são só config
servers
para saber em qual shard
ele deve se conectar.
Criando
um cluster…
Primeiro
(config server)
Precisamos
criar uma pasta com o nome configdb,
dentro de data
que fica na pasta raiz. Essa pasta será usada para o nosso config
server.
cd
/
mkdir
/data/configdb
mongod
--configsvr --port 27010
O
ideal é criamos mais de um config
server,
porque caso o nosso config
caia o router
ficar perdido. Então para evitarmos falhas, devemos criar outros
config.
Segundo
(router)
Agora
iremos levantar o nosso router, passando a porta do nosso config
server.
Lembre-se de executar em uma nova aba/janela.
mongos
--configdb localhost:27010 --port 27011
Terceiro
(shards)
Criaremos
pastas onde ficaram nossas shards,
dentro também da pasta data.
cd
/
mkdir
/data/shard1 && mkdir /data/shard2 && mkdir
/data/shard3
E
iremos levantar cada shard no terminal. Cada shard precisa ser
executado em aba/janela diferente.
cd/
mongod
--port 27012 --dbpath /data/shard1
cd/
mongod
--port 27013 --dbpath /data/shard2
cd/
mongod
--port 27014 --dbpath /data/shard3
Agora
precisamos registrar nossos Shards
no nosso Router.
Para
isso devemos conectar ao Router:
mongo
--port 27011 --host localhost
Depois
registramos os shards,
passando o ip e a porta:
sh.addShard(“localhost:27012”)
sh.addShard(“localhost:27013”)
sh.addShard(“localhost:27014”)
Feito
isso, vamos especificar qual database
iremos shardear
com o comando
sh.enableSharding(“database”)
E
agora iremos selecionar a collection,
no primeiro parâmetro iremos passar o nome da database e da
collection e como segundo parâmetro o campo que era irá quebrar
para saber a faixa de dados que vai ficar em cada shard.
sh.shardCollection(“database.collection”,
{_id: 1})
No
exemplo assim, passamos a _id
para ser dividido.
Agora
quando formos fazer inserção de dados no nosso cluster, basta
executar no nosso router.
Até
a próxima ;)
MongoDB - Criando Replicas
Com
a necessidade de criar um blog para um curso, tive a ideia de
aproveitar o blog e junto com alguns amigos fazer postagens de
assuntos relacionados a Computação, como: Teoria para grafos,
Telecomunicações, Sistemas Operacionais, Desenvolvimento, entre
outros.
As
postagens servirão como estudo tanto para os autores dos post's,
como para todos os leitores que tem interesse nos assuntos abordados
e que desejam aprender cada vez mais. Essa é a nossa forma de poder
ajudar amigos e colegas da área, compartilhando conhecimentos
adquiridos de forma simples e didática para um fácil
entendimento.
Nesse
post irei explicar passo a passo como construir Replicas
no MongoDB, onde construiremos localmente um conjunto de 3 Replicas.
Todos
os comandos serão executados no terminal.
Primeiro
De
inicio precisamos criar 3 pastas novas dentro de data
(aquela mesma pasta que foi preciso criar na instalação do
MongoDB), são nessas pastas que serão armazenados os dados das
Replicas.
Segue o comando para criar as pastas pelo termial:
cd / mkdir /data/rs1 mkdir /data/rs2 mkdir /data/rs3
Segundo
Pare
todos os processos do mongod
caso esteja com algum rodando. E execute os seguintes comandos, cada
um em uma aba/janela do terminal:
cd /mongod --replSet replica_set --port 27017 --dbpath /data/rs1cd /mongod --replSet replica_set --port 27018 --dbpath /data/rs2cd /mongod --replSet replica_set --port 27019 --dbpath /data/rs3
Depois do parâmetro --replSet é colocado o nome do nosso
conjunto de replicas, logo em seguida é passado o número da porta
que será usado e o caminho da pasta que ficará as Replicas.
Terceiro
Agora
vamos levantar o nosso client
em uma nova aba/janela, passando a porta da nossa replica
primária, que no caso é a primeira que criamos.
Mongo --port 27017
Quarto
No
mongo client,
criaremos uma variável que conterá as configurações para a
criação da nossa ReplicaSet:
rsconf = {_id: "replica_set",members: [{_id: 0,host: "127.0.0.1:27017"}]}
Onde
como você pode ver, no _id
passamos o nome do nosso grupo de replicas e uma array de membros
adicionando nossa primeira replica, a
nossa replica primária.
Quinto
Agora
iremos inicializar a nossa ReplicaSet
ainda no mongo client,
passando a variável que criamos no passo anterior:
rs.initiate(rsconfig)
Se
após você receber a configuração da inicialização e você for
na aba que está sendo executado o servidor mongo de endereço
127.0.0.1:27017,
você verá algumas mensagem como a criação do oplog
e o seu tamanho, a alocação dos arquivos, a inicialização a
replicação e a transação do status, onde no final ficará como
PRIMARY.
Sexto
Agora
iremos adicionar as outras duas replicas, com o seguinte comando
(ainda no mongo client):
rs.add(“127.0.0.1:27018”)rs.add(“127.0.0.1:27019”)
Pronto!
Replicas criadas.
Os
comandos de escrita são feitos apenas na replica primária,
se você tentar fazer uma
alteração ou até mesmo uma seleção na
replica secundaria, verá que o MongoDB não vai deixar. As
modificações feitas na replica primaria serão automaticamente
sincronizadas
com as outras replicas.
Status
Você
pode executar o comando
rs.status()
Para
ver o status da replica, vendo o nome do grupo, os membros que fazem
parte, o estado de cada membro (primário ou secundário). É muito
interessante.
Também
podemos ver o status do oplog, executando
rs.printReplicationInfo()
Onde
mostra o tamanho do oplog e quando foram registrado as alterações.
No
MongoDB temos um comando para rebaixar nossa replica primária,
isso serve para você poder simular o que aconteceria se o servidor
da nossa replica caísse. O comando é o seguinte:
rs.stepDown()
Quando
a replica primaria cai. As outras replicas fazem uma votação entre
elas para eleger qual será a replica principal, essa é a nossa
garantia de que mesmo que nosso servidor principal caia, nossa base
de dados continuara ativa, disponível.
Não
perca nossos post's ;)
Aaaaah!
Caso
você crie um número par de replicas é preciso criar um arbitro,
pois se sua replica primaria cair, pode haver um empate na votação,
precisando de um arbitro que terá o voto do desempate.
Para
criarmos devemos criar outra pasta, dentro de data
no diretório raiz.
cd / mkdir /data/arb
Depois
levante o mongod
em uma outra aba/janela utilizando o comado:
mongod --port 30000 --dbpath /data/arb –replSet replica_set
Fazendo
isso, vá no client
da nossa replica primária e adicione o árbitro:
rs.addArb(“127.0.0.1:30000”)
terça-feira, 22 de dezembro de 2015
MongoDB - Extras
Nesse
extra, iremos aprender as seguintes funções:
find().length()
count()
distinct()
limit().skip()
find(query).length()
X count(query)
Essas
duas funções fazem a mesma coisa, retornam a quantidade de
documentos encontrado na busca. Mas como sempre a uma diferença, o
count()
é mais rápido que se usar o find().length(),
já que esse último traz todos os documentos para a memorias e faz
uma interação dos dados, fazendo uma contagem dos documentos, o que
gasta mais tempo.
db.collection.find(query).length()
db.collection.count(query)
distinct('campo')
Essa
função serve para retornar os valores distintos do campo. Por
exemplo, usando a nossa database Pokedex, nossa collection possui
vários pokémons de vários tipos (water, fire, electric, …),
muitos desses tipos se repetem. Se utilizarmos o distinct
nesse campo, ele irá retornar cada tipo de existente na nossa
collection, sem repeti-los. Faça o teste.
db.pokemons.distinct('types')
Se
quiser saber quantos tipos distintos existem, basta fazer…
db.pokemons.distinct('types').length
Também
podemos ver os tipos de pokémons em ordem alfabética (A-Z)
db.pokemons.distinct('types').sort()
E
se quiser na ordem inversa (Z-A)
db.pokemons.distinct('types').sort().reverse()
Fácil,
extremamente fácil…
E
agora as relações…
Relacionamento
O
relacionamento no Mongo é diferente de bancos de dados relacionais.
No Mongo não existe o JOIN usado para juntar duas tabelas que
possuam alguns campos específicos iguais, que são usados em bancos
relacionais.
No
Mongo existem duas formas de fazer esse relacionamento, a forma
Manual e a DBRef. A manual
nada mais é, do que do que salvar o _id
de uma coleção em outra coleção que estamos relacionando, a
segunda forma, a DBRef
nada mais é do que uma convenção para
representar um documento relacional, isso inclue: $ref
(nome da coleção a ser referenciada), $id
(o ObjectId do documento referenciado) e $db
(a database onde a coleção referenciada se encontra).
Explain
O
explain mostra para a gente o que o banco está fazendo, mostrando
como ele executa as query internamente. Todos os comando que fazemos
são passados para o interpretador
e convertido para uma forma que o Mongo entenda e possa executar.
Crie uma query
e execute o seguinte comando:
db.pokemons.find(query).explain()
Como
resultado, você verá que ele retornar uma série de informações,
como
por exemplo, o namespace
que contem o nome da database
e da collection,
o parsedQuery
que mostra como a query foi interpretada pelo Mongo, o serverInfo
que mostra informações do servidor como o nome do host, porta e
versão do Mongo.
Você
pode obter mais informações, se fizer da seguinte forma:
db.pokemons.find(query).explain(“executionStats”)
Isso
trará informações extras, como a quantidade de arquivos retornados
com o find
executado, total de arquivos examinados, o tempo que levado para
fazer a pesquisa, entre outras coisas.
Index
Índice
é uma forma de deixar uma busca mais rápida. Ao criamos um index
em uma collection, o Mongo irá tratar esse campo de forma diferente,
fazendo pesquisas por esse campo de forma mais rápida. Você pode
ver o index
da sua collection com o seguinte comando:
db.collection.getIndexes()
E
pode criar index, com esse outro:
db.collection.createIndex({campo:
1})
E
se quiser remover algum index que você já criou:
db.collection.dropIndex({campo:
1})
GridFS
É
um sistema de arquivos do MongoDB que permite armazenar arquivos
binários (fotos, vídeos) diretamente no banco.
Arquivos de documento do tipo BSON é de 16 Mb, para armazenarmos
arquivos maiores utilizamos o GrindFS.
Por
exemplo, se fossemos adicionar um video de formato mp4, no sistema
GridFs,
bastaria executar:
mongofiles
-d nome_database -h ip_do_host
put video.mp4
Para
fazer isso localmente, podemos colocar como ip_do_host o ip local,
127.0.0.1.
Lembrando que o nome_database é a database que será criada para
armazenar os arquivos binários.
Lembrando
que esse comando é um binário e não pode ser feito no terminal do
Mongo. Deve ser feito no terminal normal.
Replica
A
replica é o espelhamento dos dados de
um servidor para outro. Um conjunto de replicas é chamado de
ReplicaSet,
onde cada ReplicaSet
pode conter 50 replicas.
A
replica funciona da seguinte forma: qualquer escrita feita na replica
primaria, a primaria irá replicar para as secundarias. Isso ocorre
em duas etapas: Initial
Sync
e a Replication.
Initial
Sync
Esse
é a primeira etapa na replicação. Onde ele consulta cada coleção
em cada banco de dados de origem e insere todos os dados em suas
próprias cópias dessa seleção, é dessa forma que é feita a
clonagem dos bancos de dados. Esse processo de clonagem apenas copia
os dados válidos, omitindo documentos inválidos.
Depois
ele aplica as alterações para o conjunto de dados, para que depois
possa ser feito a transação para o estado secundário.
Replication
Depois
de já ter nossas replicas construídas, a Replication
vai continuar replicando e sincronizando os dados. Ele sempre fica
rodando para que cada alteração no primário seja replicado,
mantendo os membros das Replicas (ReplicaSet),
atualizados.
Oplog
É
o log de operações, qualquer alteração feito na replica primária
é colocada a ação no oplog
que é uma capped
collection
(coleções de tamanho fixo) especial. O MongoDB aplica as alterações
no primário e, em seguida, registra as operações no oplog do
primário. Onde os membros secundários, copiam e aplicam essas
operações do oplog em um processo assíncrono.
As
replicas servem para garantir que tenhamos a nossa base de dados em
outros servidores, para caso aconteça algum imprevisto no nosso
servidor principal. Por isso sempre tenha uma replica como garantia,
pois nenhum servidor é 100%.
Como
fazer replicas?
Veja
no nosso próximo post ;)
MongoDB - Update
Nesse
post será abordado a atualização no banco de dados.
Se
você leu o post sobre a inserção, viu que existe o save,
que serve tanto para inserir documentos como para alterar. Para
alterarmos o documento no save
precisamos
busca o documento, modificar e salvar, já no update
você não tem todo esse trabalho, até
porque ele permite que você altere mais de um documento de uma vez.
A
função update
recebe 3 parâmetros:
Query
Modificação
Options
E
sua sintaxe é:
db.collection.update(query,
mod, options)
No
update
o parâmetro options
é opcional.
As
buscas que fazemos é case-sensitive, para fazermos pesquisas
case-insensitive é preciso usar RegExp (expressões regulares) do
JavaScript. Assim:
/pikachu/i
Agora
iremos fazer uma atualização no documento do Pikachu, adicionando o
campo description
ao documento…
Vamos
lá…
Execute
os seguintes comandos...
var
query = {name: /pikachu/i}
query
= db.pokemons.findOne(query, {_id: 1})
var
poke = db.pokemons.findOne(query, {_id: 0})
var
mod = {description: “O Pikachu é um dos pokémons mais famosos.”}
db.pokemons.update(query,
mod)
db.pokemons.findOne(query)
Viu
o que aconteceu? Perdemos os campos que tinhamos e ficou apenas o _id
e a description.
Por isso fiz aquela query
receber o _id
do documento, pois não teríamos mais como pesquisar pelo nome.
Sabendo que perderia os dados também salvei eles na variável poke
para que pudéssemos deixar como estava antes. Então faça...
db.pokemons.update(query,
poke)
Para
podermos atualizar corretamente os dados, precisamos usar operadores
de modificação.
Operadores
de modificação
O
operador $set
modifica um valor ou cria ele, caso não exista. Sua sintaxe é a
seguinte:
{
$set: {campo: valor, campo: valor, …} }
Se
queremos adicionar a description
precisamos fazer o mod
da seguinte forma:
var
mod = {$set:
{description: “O Pikachu é um dos pokémons mais famosos.”} }
db.pokemons.update(query,
mod)
Se
podemos criar e alterar campos, também podemos remove campos de
nossos documentos, basta usar o $unset.
Sua sintaxe:
{$unset:
{description: 1}}
Para
apagarmos a description
que inserimos no documento, basta fazermos isso…
var
mod = {$unset: {description: 1}}
db.pokemons.update(query,
mod)
Para
fazermos o incremento em campos numéricos, usamos o $inc
onde passamos o campo e a quantidade que desejamos incrementar, caso
passe um valor negativo será decrementado e caso o campo não
exista, o campo será criado e setado com o valor que você passou.
{$inc:
{campo: valor}}
Veja
como é fácil incrementar. Iremos adicionar +1 no attack
do Pikachu.
var
mod = {$inc: {attack: 1}}
db.pokemons.update(query,
mod)
Para
podermos fazer modificações em campos que sejam
array, precisamos dos Operadores
de Array.
Para
inserirmos elementos no campo que seja Array, usaremos o $push.
Caso o campo que você vá inserir não seja uma Array, ele irá
retornar um erro.
{$push:
{campo: valor}}
Vamos
adicionar moves
ao Pikachu.
var
mod = {$push: {moves: “Choque do trovão”}}
db.pokemons.update(query,
mod)
O
$push
adiciona apenas um valor por vez ao campo. Para adicionarmos mais de
um valor de uma única vez, devemos utilizar o
$pushAll:
{$pushAll:
{campo: [Array_de_valores]}}
Mais
uma vez, se podemos adicionar valores em um capo do tipo array,
também podemos remover valores desses campos. Basta utilizar o
$pull:
{$pull:
{campo: valor}}
O
$pull
remove apenas um valor por vez. Para removermos mais de um valor de
uma única vez, usaremos o $pullAll…
{$pullAll:
{campo: [Array_de_valores]}}
Todos
esses operadores de modificação de array, se usados em campos que
não são array irá retornar um erro.
Options
Com
o objeto options
podemos configurar alguns valores diferentes do padrão. O options
possui os seguintes parâmetros:
{
upsert: boolean,
multi: boolean,
writeConcern: document
}
Por
padrão o upsert
e o multi
são falsos.
Upsert
Esse
parâmetro serve para caso o documento que você pesquise não seja
encontrado pela query,
ele irá criar e inserir um novo documento contendo apenas os campos
passados no mod.
$setOnInsert
Esse
operador serve para você definir valores que serão adicionados
quando ocorrer um upsert,
afinal, você não vai querer que o upsert
crie um documento com apenas um campo né!?
Como
fazer isso?
Você
passa esse operador no mod.
Veja mais ou menos como ficaria:
var
mod = { $set: {active: true}, $setOnInsert:
{name: null, attack: null, defense: null, height: null, type: null} }
Então…
Se você deixar o upsert
setado como true
e se ao fazer a busca no update
e ele não encontrar o documento, ele automaticamente criara um
documento contendo os campos do setOnInsert
e com o campo set.
Se ele encontrar o documento ele apenas faz o set.
Multi
Por
padrão, o update
permite que você modifique apenas um documento por vez, isso porque
o multi
vem setado como false,
para evitar que você faça sem querer aquele famoso, update sem
where. Para
setar como true,
basta:
var
mod = {multi: true}
writeConcern
Esse
operador descreve a garantia de que o MongoDB fornece ao relatar o
sucesso de uma operação de escrita. Para saber mais, dê uma olhada
na documentação do Mongo ;)
segunda-feira, 21 de dezembro de 2015
MongoDB - Find/FindOne
Nesse
post será abordado a pesquisa no banco de dados.
Para
brincarmos com as pesquisas seria bom que você tivesse um database
com vários dados. Nesse post usaremos um banco com pokemons para as
pesquisas.
Esse
é o link
da database. Copiei e salve em um arquivo com o nome pokemons.json e
importe os dados.
Fiz
minha importação
mongoimport
--db pokedex --collection pokemons --drop --file pokemons.json
Vamos
lá!
Nesse
post iremos falar sobre o find e o findOne. Mas antes
uma curiosidade sobre o _id (UUID – Universally Unique Identifier)
esse atributo é automaticamente colocado em cada registro que você
insere no seu banco. Eles é formado por:
4-bytes:
valor que representa os segundo desde a época Unix;
3-bytes:
identificador de máquina;
2-bytes:
ID do processo;
3-bytes:
contador, começando com um valor aleatório.
Voltando…
Primeiro
o find. A sintaxe dele é a seguinte:
db.collection.find({clausulas},
{campos})
Onde
as clausulas são as condições da pesquisa e os campos são os
atributos que você quer que ele retorne na pesquisa. Clausulas
e campos, são opcionais, se você não colocá-los a pesquisa
irá retornar todos os dados da collection.
Vamos
fazer uma consulta. Primeiramente iremos criar uma variável para
colocar nossa query e em seguida executaremos a pesquisa. Na execução
da pesquisa podemos guardar ou não o resultado, para guardar para
usar uma variável recebendo a pesquisa, caso não queria guardar,
basta apenas executar o find. Veja…
var
query = {name = 'Pikachu'}
db.pokemons.find(query)
ou
var
poke = db.pokemons.find(query)
poke
Execute
e veja o que acontece.
Agora
vamos adicionar os campos que queremos que a pesquisa retorne. Ao
usarmos campos, iremos especificar o campo com 1 (TRUE) caso
queira que ele retorne ou 0 (FALSE) caso não queira o campo. Veja a
prática…
var
fields = {name: 1, types: 1}
Ou
seja, queremos que retorne apenas o nome e o tipo do pokemon, os
outros atributos não serão retornados. Mas se não quisermos que
ele retorne por exemplo o atributo created, variamos…
var
fields2 = {created: 0}
Agora
execute dois find, pois temos duas fields. E use nossa query
criada no inicio e veja a diferença…
db.pokemons.find(query,
fields)
db.pokemons.find(query,
fields2)
Você
pode ter percebido que nos dois casos o _id sempre apareceu.
Por padrão ele sempre irá aparecer, se por algum motivo você não
deseja receber, basta negar nos campos.
findOne
Bom…
O findOne basicamente faz o mesmo que o find, ele
pesquisa. A diferença é que ele retorna apenas um elemento, o
primeiro elemento que ele encontra. Sua sintaxe é a praticamente a
mesma do find, a diferença é que é acrescentado o One.
Então,
todos os comandos feitos anteriormente podem ser feito com o findOne,
basta substituir find
por findOne.
Operadores
Aritméticos
É
comum usarmos operadores aritméticos em atributos que sejam do tipo
numérico, mas no Mongo esses operadores são um pouco diferente.
Veja como é no Mongo:
<
é $lt (less than)
<=
é $lte (less than or equal)
>
é $gt (greater than)
>=
é $gte (greater than or equal)
Veja
na prática. Vamos ver quais pokemons tem um attack maior ou
igual ao Pikachu…
var
query = {attack: {$gte: 55}}
db.pokemons.find(query)
Como você pode ver… o Pikachu não é o mais forte :O
Operadores
Lógicos
Os operadores lógicos no Mongo também são um pouco diferentes, mas
é fácil, veja…
OR é $or
Not OR é $nor
AND é $and
A sintaxe é a seguinte:
$or:
[{cláusula}, {cláusula}]
$nor:
[{cláusula}, {cláusula}]
$and:
[{cláusula}, {cláusula}]
Para usarmos os operadores lógicos, precisaremos de no mínimo duas
cláusulas que passaremos como objetos ({}).
Na prática…
var
query = {$or: [{name: 'Pikachu'}, {name: 'Charmander'}]}
db.pokemons.find(query)
Operador
Existencial
Você
nunca tinha ouvido falar nisso né!? Psé… Como você já deve
saber o Mongo é Schemaless,
você
não tem
uma estrutura pré definida, o que permite que você insira dados com
campos que outros objetos não tem. É ainda que entra o operador
existencial, você usa ele na busca para retornar apenas os objetos
que possuam aquele campo.
A
sintaxe é simples:
db.collection.find({
nome_do_campo: {$exists: true} })
Para
fazermos buscas em array precisamos usar outros operadores. Mas não
se preocupe, é fácil.
Veja!
Caso
deseja fazer uma busca em algum campo do tipo array e quer que
retorne os documentos que possuam algum dos valores que você passou,
basta usar o $in.
var
query = {campo:
{$in: [array_de_valores]}}
db.pokemons.find(query)
O
$in
é o OU
na
nossa busca em array.
No
Mongo também temos o $nin,
que retorna os documentos que não possuem os valores que você
passou na pesquisa.
{campo:
{$nin:
[array_de_valores]}}
db.pokemons.find(query)
E
se temos um “OU” também temos um “AND”, que é o $all.
Ele apenas retorna os documentos que possuem todos os valores que
você passar.
{campo:
{$all:
[array_de_valores]}}
db.pokemons.find(query)
Agora,
por fim, um operador
de negação,
que no caso seria o diferente, o $not.
var
query = {name: {$not: /pikachu/i}}
db.pokemons.find(query)
Nessa
busca que fizemos, será retornado todos os pokemons que não possuam
o nome Pikachu.
Por
hoje, é isso. Até o próximo post!
sexta-feira, 18 de dezembro de 2015
MongoDB – Importação/Exportação e Insert/Save
Antes
de aprendermos a fazer pesquisas no MongoDB, primeiramente iremos
aprender os comando de exportação e importação para que você já
possa importar alguns dados e comece a brincar com eles durante as
consultas.
Exportação
Na
exportação os dados da collection são salvos em um arquivo JSON.
mongoexport
--db nome_do_database --collection nome_da_collection --out
arquivo.json
Importação
Os
dados salvos em um JSON são importados para uma collection do Mongo.
mongoimport
--db nome_do_database --collection nome_da_collection --drop --file
arquivo.json
Nesse
comando o --drop apaga a collection do database que você
selecionou caso ela exista, para que possa começar do zero.
Observação: Os comandos de importação e exportação devem ser feitos no terminal normalmente e com o servidor mongo ligado. A importação e exportação não é feita no cliente mongo como você pode estar pensando...
Observação: Os comandos de importação e exportação devem ser feitos no terminal normalmente e com o servidor mongo ligado. A importação e exportação não é feita no cliente mongo como você pode estar pensando...
No
GitHub tem alguns JSON que você importar e usa para testar os comandos.
Nesse
post iremos aprender sobre as formas de inserirmos dados no Mongo.
Vamos
lá!
No
Mongo existem duas formas de inserirmos os dados, são elas
db.collection.insert(documento)
ou
db.collection.save(documento)
Primeiro
iremos criar em uma variável com os dados da pessoa que iremos
inserir na collection pessoa da database agenda que foi mostrado no
post anterior. Para criarmos essa variável e inserir os dados nela,
podemos usar comandos JavaScript já que o Mongo aceita isso, um
exemplo é que se você fizer 2 + 2 no terminal do Mongo, ele executa
e te da o resultado. Veja como é simples criar uma variável para
inserirmos no na nossa collection:
var
pessoa = {
...
'name': 'Barry Allen',
...
'phones': [{'carrier': 'Claro', 'number': 912345678}]
...
}
Phones
será uma array onde poderemos colocar mais de um número, caso a
pessoa possua, por isso os [ ] (colchetes).
E dentro desses colchetes podemos colocar vários objetos, cada
objeto dentro de { } (chaves),
lembrando que um objeto pode possui vários atributos. Como no
exemplo mostrado os nosso objeto possui os atributos carrier
e number. Agora outro
exemplo onde phones
possui dos objetos:
var
people = {
"name": "Hal Jordan",
"phones": [
{
"carrier": "Claro",
"number": 987654321
},
{
"carrier": "Tim",
"number": 956781234
}
]
}
Fácil,
né!?
Temos
dois contatos como exemplo. Vamos inserir usando o insert.
Primeiro:
db.pessoa.insert(pessoa)
depois:
db.pessoa.insert(people)
Para
cada inserção deverá aparecer algo semelhante a isso (estou usando
o MongoHack)...
Inserted
1 record(s) in 3ms
WriteResult({
"nInserted": 1
})
Essa
mensagem mostra o tempo levado para fazer a inserção e diz quantos
documentos foram inseridos.
Agora
o save. Pode ser
estranho ter dois comandos para inserir objetos no nosso banco, mas
existe uma diferença entre eles, para poderemos ver essa diferença
precisaremos usar o comando findOne(). Os comando de pesquisa
explicarei mais a fundo no próximo post e
a diferença do save
você verá na prática.
Continuando…
Vamos
criar uma variável que será nossa query, essa variável irá conter
o que queremos pesquisar no banco de dados. Iremos pesquisar o nome
'Barry Allen', para
isso nossa variável precisara ter o atributo que irá verificar (no
caso o name) e o nome.
Vejá como fica…
var
query = {'name': 'Barry Allen'}
Agora
iremos usar uma outra variável para receber o valor da pesquisa para
a nossa query…
var
auxiliar = db.pessoa.findOne(query)
Um
spoiler do próximo post: db.collection.find() ou
db.collection.find({}) exibi todos os dados da collection, lembre se
que no nosso caso a nossa coleção é pessoa.
A
variável auxiliar irá receber de findOne()
o resultado da busca para o nome Barry Allen… Se depois desse
comando, você digitar auxiliar
e der ENTER, você verá isso…
{
"_id":
ObjectId("567479879a3b551315ed44c8"),
"name": "Barry
Allen",
"phones": [
{
"carrier": "Claro",
"number": 912345678
}
]
}
Fácil,
fácil. Reparou no atributo “_id”?
Ao inserirmos um objeto no banco, automaticamente é criado um
identificador
desse objeto, é a forma de diferenciarmos cada objeto. Podemos até
ter dois objetos com os mesmo dados, mas ele serão diferentes, pois
possuirão id's
diferentes.
Agora
iremos alternar nossa variável auxiliar, adicionando um atributo, o
nickname (apelido) que receberá The Flash.
auxiliar.nickname
= 'The Flash'
Você
pode executar auxiliar, para ver como ficou com a modificação. Veja
que essa modificação foi feita apenas na variável, para que seja
inserida no banco de dados e atualizar o contato que tem o nome do
Barry Allen, usaremos o save…
db.pessoa.save(auxiliar)
Você pode utilizar o comando…
db.pessoa.find()
Para ver todas as pessoas que inserimos, no caso, você poderá ver
que o objeto com nome de Barry Allen possui um atributo a mais. Isso
graças ao nosso save. Ai já deu para perceber a diferença
né!?
E se fizesse isso com o insert? Iria da erro. Pois o save
verifica se existe algum objeto com o mesmo id, caso tenha ele
apenas altera, caso não tenha ela insere. Já o insert se
você tentar fazer o mesmo processo trocando o save pelo
insert, irá da erro, o Mongo vai dizer que já existe um
objeto com o mesmo _id.
E é isso.
Agora
você já sabe inserir e ver os dados. Até o próximo post ;)
