Configure your CLI to MongoDB, bro:
$
- To initialize, run
mongod
- To get in the mongo, run
mongo
- If you get some error like this
Address already in use for socket: 0.0.0.0:27017
that's because you already have a process running. Trykillall mongod
and back to the 1st step - Then you can test. Run
show dbs
. Ex:
din-mac03(mongod-3.0.5) test> show dbs
be-mean → 0.078GB
local → 0.078GB
On the time you gonna connect, you can tell that you want to get the database up with the db's name. Example:
mongo be-mean
Then we won't need to run mongo
and after use be-mean
.
db.collection_name.insert({attr : value})
Ex:
db.students.insert({name:"Caue", age: 20})
var stu = {name: "Clyde", age : 20}
db.students.insert(stu)
The db.save()
insert and save at the sime time o_o. Example:
var pokemon = {
'name' : 'Caterpie',
'description' : 'Larva lutadora',
'type' : 'insect',
'attack' : 30,
'height' : 0.3
}
db.pokemons.save(pokemon)
For example, let's add an attr - using findOne
var query = {name : 'Caterpie'}
var p = db.pokemons.findOne(query)
p.name
p.defense = 35
Then we need to salve it:
db.pokemons.save(p)
var cur = db.pokemons.find()
// It is not an array, else I could do a for each.
while(cur.hasNext()) {
print(tojson(cur.next()))
}
We use also the fields to search. Ex:
var query = { name : 'pickachu'}
var fields = {name : 1, description: 1}
db.pokemons.find(query, fields);
Always the _id
cames with the query. If you want it, you just need to denied this field. Ex:
var query = { name : 'pickachu'}
var fields = {name : 1, description: 1, _id: 0}
db.pokemons.find(query, fields);
The output:
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query, fields);
{
"name": "pickachu",
"description": "Non ecxiste"
}
- Less than :
$lt
=<
- Less Than or Equal :
$lte
=<=
- Greater than
$gt
=>
- Greater than or Equal :
$gte
=>=
< : $lt
<= : $lte
> : $gt
>= : $gte
An example:
var query = { height: { $lt: 5 } }
db.pokemons.find(query)
var query = { height: { $lte: 0.5 } }
db.pokemons.find(query)
var query = { height: { $gt: 0.5 } }
db.pokemons.find(query)
var query = { height: { $gte: 0.5 } }
db.pokemons.find(query)
$or
var query = { $or : [ {name : 'pickachu'}, {height: 1.69} ] }
db.pokemons.find(query)
$nor
var query = { $nor : [ {name : 'pickachu'}, {height: 1.69} ] }
db.pokemons.find(query)
$and
var query = { $and : [ {name : 'pickachu'}, {height: 1.69} ] }
var query = { $and: [ {attack: {$gte: 48}}, {height: {$lte: 0.5}} ]}
db.pokemons.find(query)
$exists
It searchs for objects that HAS that field. So, it returns the object IF the fields exists.
Syntax: db.collection.find({ my_field: {$exists : true} })
An example w/ pokemons:
var query = {name : {$exists : true}}
db.pokemons.find(query)
It get three parameters.
- Query
- Modification
- Options
db.collection.update(query, mod, options)
Let's create a new pokemon:
var poke = {
name : 'Testemon',
attack : 8000,
defense : 8000,
height: 2.1,
description: 'Pokemon de teste'
}
db.pokemons.save(poke)
Let's search it:
var query = { name : /testemon/i }
db.pokemons.find(query)
Now let's search with _id
:
var query = {"_id": ObjectId("564a58b642d23c8c2ce6d1bd")}
var mod = {description : 'Mudei aqui'}
So, let's modify the object's description that has id = that one.
db.pokemons.update(query, mod)
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("564a58b642d23c8c2ce6d1bd"),
"description": "Mudei aqui"
}
Fetched 1 record(s) in 0ms
All the others properties of the object was removed.
So let's build the update on the right way:
It will modify the field. If it does not exists, it'll create.
{ $set: {field: value}}
So let's reuse the query
var that we made and insert into it the rest of the properties:
Our query
is:
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> query
{
"_id": ObjectId("564a58b642d23c8c2ce6d1bd")
}
var mod = {
$set : {
name : 'Testemon',
attack : 8000,
defense : 8000,
height: 2.1,
description : 'Pokemon de teste'
}
}
Note that the fields that does not exists will be created automagicly:
db.pokemons.update(query, mod)
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("564a58b642d23c8c2ce6d1bd"),
"description": "Pokemon de teste",
"name": "Testemon",
"attack": 8000,
"defense": 8000,
"height": 2.1
}
Fetched 1 record(s) in 1ms
It delete fields from json document.
var mod = {$unset : {height: true/1}}
db.pokemons.update(query, mod)
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("564a58b642d23c8c2ce6d1bd"),
"description": "Pokemon de teste",
"name": "Testemon",
"attack": 8000,
"defense": 8000
}
Fetched 1 record(s) in 0ms
Increment field. It increment a value with value we want. If you want to decrease, just paste the negative value:
$inc : {field : value}
Example:
var mod = {$inc : {attack : 1}}
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.update(query, mod)
Updated 1 existing record(s) in 41ms
WriteResult({
"nMatched": 1,
"nUpserted": 0,
"nModified": 1
})
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("564a58b642d23c8c2ce6d1bd"),
"description": "Pokemon de teste",
"name": "Testemon",
"attack": 8001,
"defense": 8000
}
Decreasing:
var mod = {$inc : {attack : -1}}
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.update(query, mod)
Updated 1 existing record(s) in 2ms
WriteResult({
"nMatched": 1,
"nUpserted": 0,
"nModified": 1
})
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("564a58b642d23c8c2ce6d1bd"),
"description": "Pokemon de teste",
"name": "Testemon",
"attack": 8000,
"defense": 8000
}
It add a value to the field of array. If does not exists, it'll create adding it. If is not an array, it'll returns an error.
{$push : { field: value }}
An example:
var query = {name : /pickachu/i}
var mod ={$push: {moves: 'Choque do trovão'}}
db.pokemons.update(query,mod)
An error example:
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> var mod ={$push: {type: 'Choque do trovão'}}
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.update(query,mod)
The field 'type' must be an array but is of type String in document {_id: ObjectId('5645233d141cff9e62ddfbec')}
WriteResult({
"nMatched": 0,
"nUpserted": 0,
"nModified": 0,
"writeError": {
"code": 16837,
"errmsg": "The field 'type' must be an array but is of type String in document {_id: ObjectId('5645233d141cff9e62ddfbec')}"
}
})
Add each value that you pass on the array.
Syntax:
{ $push : {field : **[array]**} }
Example:
var attacks = [
'choque elétrico',
'ataque rápido',
'bola elétrica'
]
var mod = {$pushAll : {moves : attacks}}
db.pokemons.update(query, mod)
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("5645233d141cff9e62ddfbec"),
"name": "pickachu",
"description": "Non ecxiste",
"type": "electric",
"attack": 0.1,
"defense": 0.5,
"height": 0.01,
"moves": [
"Choque do trovão",
"choque elétrico",
"ataque rápido",
"bola elétrica"
]
}
Fetched 1 record(s) in 1ms
Take out the field's value, if field is an array and exists.
Syntax:
{$pull : {field: value}}
Example: let's remove 'bola elétrica' from pickachu.
var mod = {$pull : {moves : 'bola elétrica'}}
db.pokemons.update(query, mod)
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("5645233d141cff9e62ddfbec"),
"name": "pickachu",
"description": "Non ecxiste",
"type": "electric",
"attack": 0.1,
"defense": 0.5,
"height": 0.01,
"moves": [
"Choque do trovão",
"choque elétrico",
"ataque rápido"
]
}
Fetched 1 record(s) in 0ms
Remove each value from an array field.
Syntax:
{$pullAll : {field : **[array]**}}
Let's two attacks from pickachu:
var attacks = [
'choque elétrico',
'ataque rápido'
]
var mod = {$pullAll : {moves: attacks}}
Caues-MacBook-Pro(mongod-3.0.5) be-mean-pokemons> db.pokemons.find(query)
{
"_id": ObjectId("5645233d141cff9e62ddfbec"),
"name": "pickachu",
"description": "Non ecxiste",
"type": "electric",
"attack": 0.1,
"defense": 0.5,
"height": 0.01,
"moves": [
"Choque do trovão"
]
}
Fetched 1 record(s) in 1ms
=======
That last parameter we saw.
{
upsert: boolean, [default=false]
multi: boolean, [default=false]
writeConcern: document
}
If the document does not exists, it will insert the object that is passing as modification.
By default it's false.
Example: let's imagine we need to activate the pokemons to read they information.
var query = { name: /pickachu/i }
var mod = { $set: {active: true} }
var options = {upsert: true}
db.pokemons.update(query, mod, options)
Now, with a pokemon that does not exists
var query = { name: /pokemondoesnotexists/ }
var mod = { $set: {active: true} }
var options = {upsert: true}
db.pokemons.update(query, mod, options)
db.pokemons.find(query)
Check that the object returned is activate, but we do not want this because it does not exists.
With it, you can define values that will be insert if an upsert occurs.
Let's search a pokemon, but it there isn't in our registers, so we'll insert it with the pattern values.
var query = {name: /naoexistemon/i }
var mod = {
// If it exists, just set the active = true, if not, set active and also
// the following data ($setOnInsert)
$set: {
active : true
},
$setOnInsert: {
name : 'naoexistemon',
attack : null,
defense : null,
height: null,
description : 'No information'
}
}
var options = {upsert: true}
db.pokemons.update(query, mod, options)
Imagine a structure database, SQL, now, imagine an update without the where
clause.
See??????? Big shit, isn't it?
By default, the multi
is false
. If you want to update many data once, you'll need to pass this parameter as true
.
Let's set the active = false
to all pokemons:
var query = {}
var mod = {$set : {active : false}}
var options = {multi : true}
db.pokemons.update(query, mod, options)
Just this way you can update many/all data.
The force of the writeConcerns determine the warranty level that yo have of this write.
Class 4th - Part 2
Array operators. We already've seen it.
So let's add more data. Let's add one attack for all pokemons.
var query = {}
var mod = {$set: {moves: ['investida']}}
// We could use $pull
var options = {multi: true}
db.pokemons.update(query, mod, options)
var query = {name: /pickachu/i}
var mod = {$push: {moves: 'choque do trovão'}}
// We could use $pull
var options = {multi: true}
db.pokemons.update(query, mod, options)
It will search for objects that has the passed value on array.
{field: {$in: [array]}}
Ex: Let's search all pokemons that has 'choque do trovão' in your docs.
Like or
.
var query = {moves: {$in: [/choque/i]}}
db.pokemons.find(query)
The $in
inverse. It will return documents that does not have that value on array.
Any pokemon that does not have choque as attack will be returned.
var query = {moves: {$nin: [/choque/i]}}
db.pokemons.find(query)
It returns docs if all values are found. Like and
.
var query = {moves: {$all: [ 'choque do trovão', 'investida' ] }}
db.pokemons.find(query)
Syntax:
{field: {$ne: value}}
DOESN'T ACCEPT REGEX
It will return the docs that has fields different the value passed out.
Let's search all pokemons there are not of bird turtle.
var query = {type: {$ne: 'turtle' }}
db.pokemons.find(query)
Let's select all poke that aren't pickachu.
var query = {name: {$not: /pickachu/i }}
db.pokemons.find(query)
It remove documents.
If you want to delete the collection, use drop
.
var query = { "_id": ObjectId("564cff8a2dc71abf3dc1f720") }
db.pokemons.find(query)
db.pokemons.remove(query)
WARNING: IF YOU PASS AN EMPTY QUERY, IT WILL REMOVE ALL THE DATA. The mongodb just doesn't do shit with update
.
distinct()
limit.skip()
count() - find().length()
group()
aggregate()
Use be-mean
, restaurants.
How we can see how many data there are? Like this:
db.restaurantes.find().length()
But this is very slow. So let's use count
:
db.restaurantes.count()
We can pass parameters:
db.restaurantes.count({ "borough": "Manhattan" })
We just want to know - like SQL - which one and how many are some data. So, let's see which are the borough.
db.restaurantes.distinct('borough')
be-mean> db.restaurantes.distinct('borough')
[
"Manhattan",
"Brooklyn",
"Bronx",
"Queens",
"Staten Island",
"Missing"
]
Note: as a javascript, we can sort by alfabetic order:
db.restaurantes.distinct('borough').sort()
db.restaurantes.distinct('borough').sort().reverse()
The distinct returns directly an array, so you can use .length
:
db.restaurantes.distinct('borough').length
mongoexport --host 127.0.0.1 --db be-mean-instagram --collection pokemons --out pokemons.json
mongoimport --host 127.0.0.1 --db be-mean --collection pokemons --drop --file pokemons.json
db.pokemons.find( {}, { name: 1 } )
// Or
db.pokemons.find( {}, { name: 1, _id: 0 } )
db.pokemons.find( {}, { name: 1, _id: 0 } ).limit(2)
Caues-MacBook-Pro(mongod-3.0.5) be-mean> db.pokemons.find( {}, { name: 1, _id: 0 } ).limit(2)
{
"name": "Pikachu"
}
{
"name": "Buba"
}
Fetched 2 record(s) in 1ms
So, skip the first 2:
db.pokemons.find( {}, { name: 1, _id: 0 } ).limit(2).skip(2)
For pagination, we multiply the passes and the limit. For example, let's show the first page, only showing two datas:
db.pokemons.find( {}, { name: 1, _id: 0 } ).limit(2).skip(2 * 0)
// Now the 2nd page
db.pokemons.find( {}, { name: 1, _id: 0 } ).limit(2).skip(2 * 1)
Let's imagine if we want to know how many pokemons of each type:
db.pokemons.distinct('types')
db.pokemons.distinct('types').length
db.pokemons.count({types: 'ice'})
db.pokemons.count({types: 'water'})
db.pokemons.count({types: 'fire'})
So, we need to do the same thing for to know how manu pokemon for each type? Yeah, but no.
Let's use group:
db.pokemons.group( {
initial : { total: 0 },
reduce : function(curr, result){
curr.types.forEach(function(type){
if(result[type]) {
result[type]++;
} else {
result[type] = 1;
}
result.total++;
});
}
});
If we want to do a conditional, like show only taht ones that has defense greater than 40:
db.pokemons.group( {
initial : { total: 0 },
cond : { defense : {$gt : 40} },
reduce : function(curr, result){
curr.types.forEach(function(type){
if(result[type]) {
result[type]++;
} else {
result[type] = 1;
}
result.total++;
});
}
});
Now, see how many pokemons there are with defense greater than or equal 100 and of fire's type:
db.pokemons.count( { defense: {$gte: 100}, types : 'fire' } )
Working with averages:
db.pokemons.group( {
initial : { total: 0, attack : 0 },
cond : { types : 'water' },
reduce : function(curr, result){
result.total++;
result.attack += curr.attack;
},
finalize: function(result) {
result.attack_avg = result.attack / result.total;
}
});
Note: all aggregate's functions will start with $
, because it talks to mongo this is a column.
Let's do the same: averages
db.pokemons.aggregate({
$group: {
_id : {}, // Group everybody
attack_avg : {$avg : '$attack'}, // Attack's average
attack_plus : {$sum: '$attack'},
total : {$sum : 1}
}
});
Tip: .pretty()
.
Basically, what you can do with group
you can do w/ aggregate
.
Show only of water's types:
db.pokemons.aggregate([
{$match : {type : 'water'}}, // conditional
{
$group: {
_id : {}, // Group everybody
attack_avg : {$avg : '$attack'}, // Attack's average
attack_plus : {$sum: '$attack'},
total : {$sum : 1}
}
}
]);
Corrections 4th and 5th classes.
Don't you know which database you are? Type db
.
Now w/ aggregate
:
db.pokemons.aggregate([
{ $unwind : '$types'}, // column you want to group
{ $group : {
_id : '$types',
count : { $sum : 1 }
}
}
]);
=========
THE ARE NO JOINS like SQL.
There are two ways: Manual and DBRef.
You just need to save one collection's _id
in another one.
var pokemons = [
{"_id": ObjectId("56452240141cff9e62ddfbe8")},
{"_id": ObjectId("564d02922dc71abf3dc1f721")},
{"_id": ObjectId("5645233d141cff9e62ddfbec")}
]
var json = {name : 'Meus pokemons', pokemons : pokemons}
db.invt.insert(json)
// Now let's get the create the search to get each one.
var pokemons = []
var getPokemon = function(id) {
pokemons.push(db.pokemons.findOne(id))
}
var invt = db.invt.findOne();
invt.pokemons.forEach( getPokemon )
Is a convention to represent a related document.
It says what is happening on the database.
An aleatory number between 0 and 1.
Ex: any data on database.
db.restaurantes.find().limit(1).skip( _rand() * db.restaurantes.count() )
db.restaurantes.find({ name : 'Chin' }).explain()
// Show other stuff
db.restaurantes.find({ name : 'Chin' }).explain('executionStats')
When to use the explain
?
When we want to know what happens with our queries.
Says that someone is special to get fatest than other.
Remember example between searching by name and id.
db.restaurantes.createIndex({ name : 1 }) // or -1
// Double - compound index
db.restaurantes.createIndex({ name : 1, other : 1 }) // or -1 and if find() has the two fields
// Now searching by name is fatest than earliear.
db.restaurantes.dropIndex({ name : 1 }) // or -1
Now the search by name
is sucks again.
MongoDB's File system. It armazena binary files. Like a blob from related.
-
Do not put all files on RAM.
-
Réplicas
-
When you need to access data from a big file no loading ALL the file.
On a simple terminal, run:
mongofiles -d be-mean-files -h 127.0.0.1 put Os_Raios_do_Pikachu.mp4
Go to mongo:
use be-mean-files
be-mean-files> show collections
fs.chunks → 21.124MB / 26.559MB
fs.files → 0.000MB / 0.008MB
system.indexes → 0.000MB / 0.008MB
``
Chunk: binary files
Files: the files, er.
### TIP
Use on your own server.
# Replica
Data mirror - espelhamento de dados.
## ReplicaSet
Replicas Emsemble - even 50 replicas.
### Initial sync
...
### Replication
It continued to replicate and syncronyze the stuff.
### OPLOG
Operation log.
### Why use?
Because we need to garantee our data and the replica...
### When use?
**ALWAYS**.
### How to use?????????????????
1. Create directories
```js
// One for each replica that we'll initialize
mkdir/data/rs1
mkdir/data/rs2
mkdir/data/rs3
- Create the servers
// One for each terminal
mongod --replSet replica_set --port 27017 --dbpath /data/rs1
mongod --replSet replica_set --port 27018 --dbpath /data/rs2
mongod --replSet replica_set --port 27019 --dbpath /data/rs3
Continue here.
Connect on specific port:
mongo --port 27019
rs.status()
Oplog status:
rs.printReplicationInfo()
rs.stepDown()
// It drop down the mongo and reconnect it on port as secondary.
...
Have the power to help - vote - to decide which secundary will be turn the secondary.
Add only when have a pair of members.
// Create a directory where have the arbitro's configuration.
mkdir /data/arb
// Get up w/ mongo
mongod --port 30000 --dbpath /data/arb --replSet replica_set
// Connect on the primary replca
rs.addArb('127.0.0.1:30000')
- vote
- heartbeats
- config data
It's the proccess of data storage in many machines.
More processment power - HD, RAM - on the same server - you group up to upside.
You add more servers and distribute the charge between them, not just for one.
Because your server does not endure.
When you analyze your data and see your collection's size is getting close of the server's memory size that it has to mongodb.
- Shards
- Configserver
- Router - 10:44s
sudo mkdir /data/configdb
sudo mongod --configsvr --port 27010
mongos --configdb localhost:27010 --port 27011
// Create first all the three shard's directories
sudo mkdir /data/shard1
sudo mkdir /data/shard2
sudo mkdir /data/shard3
// Now we need to stand them up - create/connect
// shard 1
sudo mongod --port 27012 --dbpath /data/shard1
// shard 2
sudo mongod --port 27013 --dbpath /data/shard2
// shard 3
sudo mongod --port 27014 --dbpath /data/shard3
// Now, register the shards on the router
```js
sh.addShard()
// First of all, connect on router
mongo --port 27011 --host localhost
// After register the shards
use be-mean
sh.addShard('localhost:27012')
sh.addShard('localhost:27013')
sh.addShard('localhost:27014')
// Now we'll specify which database we will shardear
sh.enableSharding('be-mean')
// Now, let's specify which collection of this database will be sharded.
sh.shardCollection('be-mean.notas' , {'_id' : 1} )
// Then add data to our cluster on the router:
for(i = 0; i < 100000; i++) {
db.notas.insert({tipo:'prova', nota : Math.random()*100, estudante_id: i, active:true,date_created:Date.now(),escola:'Webschool', país:'Brasil', rg: i*3});
}
// Now we can check
db.notas.find()
db.notas.count()
db.notas.find().explain()
db.notas.find({'rg' : 21}).explain()
db.notas.find({'_id' : 21}).explain()
db.notas.find({'_id' : 99999}).explain()
All the data of auth and authorization stays in system.users collection.
{
createUser: '<name>',
pwd : '<Password>',
customData : {<any info>},
roles : [
{role : '<role>', db: '<database>' } | '<role>',
...
],
digestPassword : boolean, //optional
writeConcern : {<write concern>}
}
### Required access
You need have `granRole` action.
### Creating an Admin user
use admin
db.createUser( { user : 'CaueAdmin', pwd : 'admin123', roles : [{role:'userAdminAnyDatabase', db : 'admin'}] } )
// Response
Successfully added user: { "user": "CaueAdmin", "roles": [ { "role": "userAdminAnyDatabase", "db": "admin" } ] }
### Update user
```js
// Syntax
{
updateUser : '<username>',
pwd : '<passhere>',
customData : {<any info>}
roles : [{role:'userAdminAnyDatabase', db : 'admin'} | '<role>',...],
writeConcern : { < writeConcern > }
}
30:21
You need have revokeRole
action.
Example:
db.runCommand({
updateUser : 'CaueAdmin',
customData : {student : true}
})
When you update the paper's array, you'll substitute all the values from earlier array.
To add or remove without substitute, use the grantRolesToUser
and/or revokeRolesFromUser
commands.
It need the dropUser
action.
// Syntax
{
dropUser : '<user>',
writeConcern : { < writeConcern > }
}
Example:
db.runCommand({
dropUser : 'CaueAdmin',
writeConcern : { w : 'majority', wtimeout : 5000 }
})
// Check
db.system.users.find()
// ....
It needs the dropUser
action.
Example:
db.runCommand({
dropAllUsersFromDatabase : 1,
writeConcern : { w : 'majority', wtimeout : 5000 }
})
Add papers to users.
Needs the grantRole
action.
Remove papers to users.
Needs the revokeRole
action.
Needs the revokeRole
action.
db.runCommand({usersInfo:1})
### Connect authenticating
```js
// 1st
mongod --auth --port 27017
// Then connect on it using:
mongo --port 27017 -u 'TestAdmin' -p 'admin123' -- authenticationDataBase 'admin'
Also:
use admin
db.auth('TesteAdmin' , '123')
A document need to be EVEN 16MB, on maximum.
Como o sistema pergunta as coisas pro banco. It's different than SQL databases.
Stand without authentication and after that you open the Robomongo.
Here.
2 => Usuário comum sem role.
Here.