Why Computers Can't Count Sometimes
https://youtube.com/embed/RY_2gElt3SA
Conceptos
Scale up — Escalado vertical — Mellorar a máquina
Scale out — Escalado horizontal — Meter máquinas
Basically Available Soft State Eventually Consistent
Sólo dous de tres
Tamén chamados arrays asociativos
JavaScript Object Notation
{
nome: 'Juan',
apelidos: 'Sánchez',
idade: 19,
titor: {
nome: 'Jose Sánchez',
email: 'jose@local'
},
modulos: [
'Big Data Aplicado',
'Sistemas de Big Data',
]
}
MongoDB manexa documentos BSON (JSON en formato binario).
Non hai traducción directa correcta
Asumamos esta mentira para entendernos:
Non te perdas! mongosh, compass, atlas. Quen e quen?
docker run --name mongo \
-e MONGO_INITDB_ROOT_USERNAME=mongoadmin \
-e MONGO_INITDB_ROOT_PASSWORD=abc123Secret \
-v /root/mongo:/data/db \
-p 27017:27017 \
mongo
docker exec -it mongo \
mongosh --host localhost --port 27017 --apiVersion 1 \
--username mongoadmin --password abc123Secret
docker network create mongoR
docker run -d -p 27017:27017 --name mongoVermello \
--network mongoR mongo mongod \
--replSet coresRGB \
--bind_ip localhost,mongoVermello
docker run -d -p 27027:27017 --name mongoVerde \
--network mongoR mongo mongod \
--replSet coresRGB \
--bind_ip localhost,mongoVerde
docker run -d -p 27037:27017 --name mongoAzul \
--network mongoR mongo mongod \
--replSet coresRGB \
--bind_ip localhost,mongoAzul
docker exec -it mongoVermello mongosh --eval "rs.initiate({
_id: \"coresRGB\",
members: [
{_id: 0, host: \"mongoVermello\"},
{_id: 1, host: \"mongoVerde\"},
{_id: 2, host: \"mongoAzul\"}
]
})"
docker exec -it mongoVermello mongosh --eval "rs.status()"
usuario@local:~$ mongosh [--host localhost]
test> quit
db.auth("USUARIO", passwordPrompt() )
db.help()
db.hostInfo()
Date()
mongosh "mongodb+srv://host-ou-servidor/BBDD" \
--apiVersion 1 --username O-MEU-USUARIO
Opcional: URL co usuario e contrasinal embebidos:
mongodb://usuario:contrasinal@host:27017/?authMechanism=DEFAULT
test> use database1
database1> db
database1> show dbs
database1> db.dropDatabase()
database1> db.createCollection("laColeccionEjemplo")
database1> show collections
database1> db.laColeccionEjemplo.drop()
test> use holamundo
holamundo> db.holamundo.insertOne({'hola': 'mundo'})
holamundo> show collections
holamundo> show databases
Unha base de datos e unha colección créanse automáticamente ao crear un documento
use persoal
db.createUser({user: "profesor123",
pwd: passwordPrompt(), // ou "o contrasinal en claro"
roles: [ { "readWrite", "dbAdmin" },
{ role: "readWrite", db: "biblioteca" }
]})
use baseDatos
db.getUsers()
// NON pases traballo! Por que?
use videoclub
db.createUser({user: "topicazo",
pwd: "aqui-non-debe-ir",
roles: [ { role: "readWrite", db: "videoclub" },
{ role: "readWrite", db: "concesionario" }
]})
docker exec -it mongoVermello \
mongosh --host localhost --port 27017 --apiVersion 1 \
videoclub --username topicazo --password aqui-non-debe-ir
Funcionouche? Por que?
Ollo! o usuario está na BD videoclub
docker exec -it mongoVermello \
mongosh --host localhost --port 27017 --apiVersion 1 \
concesionario --username topicazo --password aqui-non-debe-ir \
--authenticationDatabase videoclub
use admin
db.createUser({user: "adnauseam",
pwd: passwordPrompt(),
roles: [ { role: "dbAdmin", db: "alumnado" },
{ role: "dbAdmin", db: "profesorado" },
{ role: "dbAdmin", db: "biblioteca" }
]})
docker exec -it mongoVermello \
mongosh --host localhost --port 27017 --apiVersion 1 \
alumnado --username adnauseam \
--authenticationDatabase admin
db.estudantes.insertOne( {
nome: 'Juan',
apelidos: 'Sánchez',
idade: 19,
titor: 'Jose Sánchez',
modulos: ['Big Data Aplicado', 'Sistemas de Big Data']
})
db.estudantes.countDocuments()
db.estudantes.insertMany([
{...},
{...}
])
db.estudantes.countDocuments()
Baixa aquí o exemplo con unha e varias insercións
db.docentes.insertMany( [
{nome: "Jose Sánchez", email: 'jose@local'},
{nome: "Juan Torre", email: 'juan@local'} ])
db.estudantes.find()
ou
db.estudantes.find({})
É un campo composto por 12 bytes:
Ademáis:
covid> db.coviditalia.find({})
Pódense limitar o número a amosar
covid> db.coviditalia.find({}).limit(3)
Por defecto mongosh limita a 20 e podemos pedir mais co comando it (iterar).
covid> db.coviditalia.find().sort({data:1})
covid> db.coviditalia.find().sort({data:-1})
db.estudantes.find().sort({idade: 1})
db.estudantes.find().sort({idade:-1})
Útiles para obter só algúns atributos.
db.estudantes.find( {},
{nome: 1,
apelidos: 1,
idade: 1,
titor: 1})
db.estudantes.find({}, {modulos: 0})
Fan o mesmo?
db.estudantes.find({idade:19})
db.estudantes.find( {idade: {$lte: 19} } )
db.estudantes.find({ titor:
{$in : ["Jose Sánchez", "Juan Torre"] } })
Tamén podemos querer filtrar por un elemento dun array, para iso empregamos .X (onde X é un índice que comeza en 0)
db.estudantes.find(
{"modulos.0": "Sistemas de Big Data"}).pretty()
db.estudantes.find({modulos: 'Sistemas de Aprendizaxe'})
db.estudantes.find({modulos:
{$elemMatch: {$eq: 'Sistemas de Aprendizaxe'}}})
$elemMatch admite varias condicións
{ : { $all: [ , ... ] } }
O array debe ter todos os elementos
db.estudantes.find({modulos : {$all: ['Sistemas de Big Data',
'Big Data Aplicado',
'Modelos de Intelixencia Artificial',
'Programación de Intelixencia Artificial',
'Sistemas de Aprendizaxe'] }})
Operador | Sintaxe |
---|---|
Igual | {clave1: 'valor1'} |
Menor | {clave1: {$lt: 123.45} } |
Menor igual | {clav: {$lte: 123.45} } |
Maior | {clav: {$gt: 123.45} } |
Maior igual | {clav: {$gte: 123.45} } |
Distinto | {clav: {$ne: 123.45} } |
{ {key1: 'value1', key2: 'value2'} }
{
$or: [
{key1: 'value1'}, {key2: 'value2'}
]
}
{
atributo1: 'valor1',
$or: [
{atributo2: 'valor2'}, {atributo3: {$gte: valor3} }
]
}
db.estudantes.countDocuments({QUERY}, {opcións})
db.estudantes.estimatedDocumentCount()
db.estudantes.countDocuments({idade: 19}, {opcións})
Opcións (opcionais):
db.estudantes.find( {titor: "Jose Sánchez", idade: {$gt: 20}})
db.estudantes.find( {titor: "Juan Torre", idade: {$lt: 21}})
db.estudantes.find( {
$or: [
{titor: "Jose Sánchez"}, {idade: {$gte: 23}}] })
db.estudantes.updateOne(filtro, actualizacion, opcións)
{$set: {...} }
Muda ou engade valores
db.estudantes.updateOne({nome: 'Luis'},
{$set: {'Curso': '2022/2023'}})
{$push: {...} }
Engade un elemento a un array (ou crea o array co elemento)
db.estudantes.updateMany({nome: 'Luis'},
{$push: {'modulos': 'FOL'}})
Quita un elemento dun array por posición
db.estudantes.updateMany( { },
{ $pop: { modulos: 1 } })
Borra dun array tódolos valores que cumplen unha condición.
{ $pull: { campo1: ,
campo2: , ... } }
Borra "FOL" e "Matemáticas" dos módulos.
Quita "Titor de proba" do array (se hai) de titores legais.db.estudantes.updateMany( { }, { $pull: { modulos: { $in: [ "FOL", "Matemáticas" ] }, titores_legais: "Titor de proba" } } )
Quita un campo dos documentos.
db.estudantes.updateMany(
{ },
{ $unset: { curso_academico: "" } }
)
db.estudantes.updateOne(
{nome: 'Alumno de Proba'},
{$set: {email: 'noreply@local'}},
{upsert:true} )
Evita a Race Condition típica. Actualiza e devolve o rexistro
Sumar un caso de COVID
use covid
db.coviditalia.findAndModify({
query: {
data: '2020-02-24T18:00:00',
stato: 'ITA',
codice_regione: 13,
denominazione_regione: 'Abruzzo',
codice_provincia: 66,
denominazione_provincia: "L'Aquila",
sigla_provincia: 'AQ',},
update: {$inc: {totale_casi: 1}},
create:true})
use alumnado
db.estudantes.updateMany({},
{$set: {'curso_academico': '2022/2023'}})
db.colecion.replaceOne(filtro, reemplazo, opcións)
Útil xa que mantén o mesmo _id mudando o resto de datos dunha vez
db.coleccion.deleteOne/deleteMany(filtro, opcións)
db.collection.findOneAndDelete()
db.collection.bulkWrite()
db.estudantes.deleteOne({nome: 'Luis'})
db.estudantes.deleteMany({curso_academico: '2022/2023'})
A través dunha serie de procesos conectados entre si (agregation pipeline) os datos poden pasar por operacións (unha cada vez) que:
db.colecion.aggregate( [
{$stage_name: { expresión } },
{$stage_name: { expresión } }
])
Da rexión 15, cantos datos ten de cada provincia?
db.coviditalia.aggregate( [
{ $match: {"codice_regione": 15}},
{ $group: {
_id: "$codice_provincia",
total_provincias: {$count:{}} }
}
])
Da rexión 15, cantos datos ten de cada provincia?
db.coviditalia.aggregate( [
{ $match: {"codice_regione": 15}},
{ $group: {
_id: "$codice_provincia",
total_provincias: { $count:{} } }
},
{ $limit: 5 }
])
Amosar as claves:
data, estado, idrexion e nomerexion da rexión 15:
db.coviditalia.aggregate( [
{ $match : {"codice_regione": 15}},
{ $project : {
data: 1,
estado: "$stato",
idrexion: "$codice_regione",
nomerexion: "$denominazione_regione"}}
])
db.coviditalia.aggregate( [
{ $match : {"codice_regione": 15}},
{ $project : {
data: 1,
estado: "$stato",
idrexion: "$codice_regione",
nomerexion: "$denominazione_regione"}},
{$out: "rexions_en_galego"}
])
db.alumnado.updateOne(
{_id: 1234},
{
{$set: {
nome: 'Felipe',
modulos: ['FOL', 'Programación I'],
titor: 'Outro profe'
} }
}
)
Podería ser considerada ACID, posto que hay 3 actualizacións e se executan ou todas ou ningunha. Pode afectar tamén a subdocumentos.
const asesion = db.getMongo().startSession()
asesion.startTransaction()
const estudantesmedran=
asesion.getDatabase('alumnado').getCollection('estudantes')
estudantesmedran.updateMany({}, {$inc : {'idade': 1}})
asesion.commitTransaction()
Preme AQUÍ e baixa o exemplo do JSON para Atlas
MongoServerError: Transaction numbers are only allowed on a replica set member or mongos. Ollo! Non existen transaccións cando mongodb está en modo «standalone».
const asesion = db.getMongo().startSession()
asesion.startTransaction()
const ops =
asesion.getDatabase('alumnado').getCollection('estudantes')
asesion.commitTransaction()
asesion.abortTransaction()
db.collection.createIndex( { name: -1 } )
Toman o nome das claves e a dirección separados por _
Exemplo:
{nome : 1, apelidos: -1}
nome_1_apelidos-1
db.estudantes.createIndex(
{ apelidos: 1, expediente: -1 } ,
{ name: "Notas e apelidos" } )
db.estudantes.getIndexes()
db.estudantes.createIndex( {apelidos: 1},
{collation: {locale: "es"}} )
Empregámolo nunha consulta find:
db.estudantes.find({apelidos: "Sánchez"})
.collation({locale: "es"})
Pero ollo, se temos activado o cotexo binario «simple», non poderemos empregar o índice:
db.estudantes.find({apelidos: "Sánchez"})
{
"name": "sample_supplies-sales-dynamic",
"searchAnalyzer": "lucene.standard",
"analyzer": "lucene.standard",
"collectionName": "sales",
"database": "sample_supplies",
"mappings": {
"dynamic": true
}
}
Exemplo do titorial oficial
atlas clusters search indexes create \
--clusterName myAtlasClusterEDU \
-f /app/search_index.json
atlas clusters search indexes list \
--clusterName myAtlasClusterEDU \
--db sample_supplies --collection sales
mongosh -u myAtlasDBUser -p myatlas-001 \
$MY_ATLAS_CONNECTION_STRING/sample_supplies
db.sales.aggregate([
{
$search: {
index: 'sample_supplies-sales-dynamic',
text: {
query: 'notepad', path: { 'wildcard': '*' }
} } },
{
$set: {
score: { $meta: "searchScore" }
}
}
])
db.estudantes.createIndex({titor: "text"})
db.estudantes.find({$text:{$search:"Sánchez"}})
Crear o índicedb.estudantes.createIndex({titor: "text", apelidos: "text"})
Empregalodb.estudantes.find({$text:{$search:"Sánchez"}})
db.estudantes.createIndex(
{ apelidos: 1 },
{ hidden: true }
);
db.estudantes.createIndex( { apelidos: 1, nome: 1 } );
db.estudantes.hideIndex( "apelidos_1_nome_1" );
db.estudantes.hideIndex( { apelidos: 1, nome: 1 } );
db.estudantes.getIndexes()
Dúas maneiras, ou especificando os índices (se é composto):
db.estudantes.unhideIndex( { apelidos: 1, nome: 1 } );
Ou especificando o nome:
db.estudantes.unhideIndex( "apelidos_1_nome_1" );
db.coviditalia.explain().find({codice_regione: 15})
Debemos mirar no winningPlan o valor de stage
db.coviditalia.createIndex(
"data": 1, "denominazione_regione": 1 );
Crea unha colección con documentos produto. Cada produto ten nome, descrición, prezo, categoría e fabricante. Mete alomenos 10 produtos.
Crea un índice de BBDD composto que permita buscar por tódolos campos relevantes para un usuario dunha tenda online. Fai uso do índice e demostra que funciona (pon exemplos e xustifícaos).
Crea un usuario administrador de calquer BD:
roles: [ { role: "userAdminAnyDatabase", db: "admin" },
"readWriteAnyDatabase" ]
Introduce en /etc/mongod.conf
security:
authorization: enabled
Activar o servizo
db.enableFreeMonitoring()
Desactivar o servizo
db.disableFreeMonitoring()
Desactivar telemetría
disableTelemetry()
Activar telemetría
enableTelemetry()
database1> db.stats()
db.estudantes.stats()
const artigosArray =
['auga', 'pan', 'leite', 'ovos'];
const mercaBucle=
(array) => array.forEach(
artigo => console.log(artigo)
);
mercaBucle(artigosArray);
Jose Sánchez
“Errare humanum est, sed perseverare diabolicum”Se atopas erros, envíame un correo a: