MongoDB

Logo
Big Data Aplicado
IA e BIG DATA

Índice

Instalación con Vagrant

Conceptos previos: NO-SQL, JSON, Key/Value...

Facendo consultas con mongosh

Instalación

  1. Clonar (ou pull) repositorio: https://github.com/jfsanchez/SBD/
  2. Ir ao directorio: escenarios/mongodb
  3. Despregar co comando:
vagrant up

Máis información (comandos e explicacións):
https://github.com/jfsanchez/SBD/tree/main/escenarios/mongodb

Conceptos previos

Conceptos previos

  • SQL
  • No-SQL — Not Only SQL
  • Clave-Valor
  • Arquivo JSON: {} e []

SQL — Structured Query Language

Creado na década dos 70 por IBM. Dende entón tivo moitos dialectos: SQL-85/88/91, SQL:1999, SQL:2003, SQL:2006, SQL:2008, SQL:2011, SQL:2016...
A tomicity
C onsistency
I solation
D urability

No-SQL — Not Only SQL

B A S E

Basically Available Soft State Eventually Consistent

Escalados

Habitualmente necesario en SQL

Scale up — Escalado vertical — Mellorar a máquina

Habitualmente en NO-SQL

Scale out — Escalado horizontal — Meter máquinas

Características NO-SQL

  • Flexibles
  • Non-Relacionales
  • Distribuídos
  • Escalables
  • Con capacidade de particionamento (Partition-Tolerant)
  • Altamente dispoñibles

Teorema de CAP (Conxetura de Brewer)

  • Consistency — Calquer lectura debe recibir como resposta a escritura máis recente ou un erro.
  • Availability — Calquer petición recibe alomenos unha resposta non errónea (sen garantía da escritura máis recente).
  • Partition Tolerance — O sistema segue funcionando de retrasarse ou descartarse mensaxes entre nodos da rede.

Sólo dous de tres

C&P (Consistency & Partition Tolerance)

  • MongoDB
  • Kafka

A&P (Availability & Partition Tolerance)

  • Apache Cassandra

Clave-Valor

Tamén chamados arrays asociativos

Wikipedia: Exemplo Clave-Valor

JSON

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).

Organización en MongoDB

Organización de MongoDB

Outros tipos de BBDD NO-SQL

  • BBDD columnares son útiles para gran volume de datos (Y-column).
  • Rápidas en lecturas, máis lentas en escritura.
  • Amazon Redshift
  • MariaDB — ColumnStore
  • SAP HANA
  • MonetDB
  • Apache Cassandra
  • Redis
  • DynamoDB

Apache Cassandra

Tipos de BBDD en Apache Cassandra

Conceptos previos — Mundo relacional

Non hai traducción directa correcta.

Asumamos esta mentira para entendernos:

  • Bases de datos ⇒ Bases de Datos
  • Coleccións ⇒ Táboas
  • Claves ⇒ Columnas/Atributos
  • Tuplas ⇒ ~"Documentos"

Conexión, Coleccións e Bases de Datos

MongoSH — Conexión

Conectar a localhost

vagrant@ubuntu-focal:~$ mongosh [--host localhost]

Saír de mongosh

test> quit

MongoSH — Bases de Datos

Seleccionar a base de datos database1

test> use database1

Indicar a base de datos actual

database1> db

Amosar as bases de datos

database1> show dbs

Borrar BBDD actual

database1> db.dropDatabase()

Creación explícita

Crear colección

database1> db.createCollection("laColeccionEjemplo")

Ver as coleccións

database1> show collections

Borrar a coleción

database1> db.laColeccionEjemplo.drop()

Creación implícita


                            test> use holamundo
                            holamundo> db.holamundo.insert({'hola': 'mundo'})
                            holamundo> show collections
                            holamundo> show databases
                        

Unha base de datos e unha colección créanse automáticamente ao crear un documento

Operacións CRUD ⇒

Inserción / INSERT

Inserción de rexistros (INSERT)


                        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()
                        

INSERT (múltiple)


                        db.estudantes.insertMany([
                            {...},
                            {...}
                        ])
                        

                            db.estudantes.countDocuments()
                        
Baixa aquí o exemplo con unha e varias insercións

Exercicio

Inserta un documento na colección "docentes". Mete os dous titores cos nomes que aparecen anteriormente e correo o nome @local.

                            db.docentes.insertMany( [
                                {nome: "Jose Sánchez", email: 'jose@local'},
                                {nome: "Juan Torre", email: 'juan@local'} ])
                        

Busca de rexistros

Busca de rexistros

A busca máis simple, que devolve todo é:

                            db.estudantes.find()
                        
ou

                            db.estudantes.find({})
                        

_id: ObjectId("123456789abc")

É un campo composto por 12 bytes:

  • 4 bytes: Timestamp (UNIX EPOCH).
  • 3 bytes: Identificador único da máquina.
  • 2 bytes: Identificador do proceso.
  • 3 bytes: Campo incremental.

Ademáis:

  • Obrigatorio: Se non existe, créase.
  • Único.

Límites

Esta liña devolve todas as tuplas
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).

Ordeamento de documentos


                            covid> db.coviditalia.find().sort({data:1})
                            covid> db.coviditalia.find().sort({data:-1})
                        
  • 1 indica de menor a maior (< ⇒ >).
  • -1 de maior a menor (> ⇒ <).

Exercicio

Coa colección alumnado, busca tódolos estudantes e ordenaos por idade (ascendente e descendentemente).

Ascendente


                                db.estudantes.find().sort({idade: 1})
                            

Descendente


                            db.estudantes.find().sort({idade:-1})
                            

Proxeccións

Útiles para obter só algúns atributos.

Opción 1: Amosar


                            db.estudantes.find( {}, 
                                {nome: 1, 
                                apelidos: 1, 
                                idade: 1, 
                                titor: 1})
                        

Opción 2: Ocultar


                            db.estudantes.find({}, {modulos: 0})
                        
Fan o mesmo?

Filtrado

  • A operación find pode recibir dous parámetros:
    • db.coleción.find( {filtro}, {proxección} )
  • No filtro podemos especificar varias condicións:
    • Coincidencia exacta:
      db.estudantes.find({idade:19})
    • Operador de filtrado:
      db.estudantes.find( {idade: {$lte: 19} } )

Filtrado: $in

Todos os documentos nos que un campo é igual a unha das opcións.

                            db.estudantes.find({ titor: 
                                {$in : ["Jose Sánchez", "Juan Torre"] } })
                        

Filtrado en arrays

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()
                        

Filtrado en arrays: $elemMatch

Que conteña o módulo (exacto) sexa ou non array


                        db.estudantes.find({modulos: 'Sistemas de Aprendizaxe'})
                        

Que sexa array (ou subdocumento) e teña o elemento


                        db.estudantes.find({modulos: 
                            {$elemMatch: {$eq: 'Sistemas de Aprendizaxe'}}})
                        
                        $elemMatch admite varias condicións
                        

Filtrado en arrays: $all


                            { : { $all: [  ,  ... ] } }
                        O array debe ter todos os elementos

Exemplo:


                            db.estudantes.find({modulos : {$all: ['Sistemas de Big Data',
                            'Big Data Aplicado',
                            'Modelos de Intelixencia Artificial',
                            'Programación de Intelixencia Artificial',
                            'Sistemas de Aprendizaxe'] }})
                        

Operadores para filtrado

OperadorSintaxe
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} }

Operadores lóxicos

AND

{ {key1: 'value1', key2: 'value2'} }

OR


                        {
                            $or: [
                                {key1: 'value1'}, {key2: 'value2'}
                            ]
                        }

Composición de operadores

Exemplo AND+OR


                        {
                            atributo1: 'valor1',
                            $or: [
                                {atributo2: 'valor2'}, {atributo3: {$gte: valor3} }
                            ]
                        }

Contando documentos

Opción 1: Cunha query

db.estudantes.countDocuments({QUERY}, {opcións})

Opción 2: Empregando os metadatos

db.estudantes.estimatedDocumentCount()

Contando documentos con countDocuments

db.estudantes.countDocuments({idade: 19}, {opcións})
Opcións (opcionais):
  • limit: Cantos documentos contar como máximo.
  • skip: Cantos documentos saltar antes de comezar a conta.
  • hint: Un índice ou a súa especificación para acelerar a conta.
  • maxTimeMS: Máximo tempo en miliseugndos para a operación de conta.

Exercicio 1: Filtra os estudantes que sexan do titor Jose Sánchez e teñan máis de 20 anos

db.estudantes.find( {titor: "Jose Sánchez", idade: {$gt: 20}})

Exercicio 2: Filtra os estudantes que sexan do titor Juan Torre e teñan menos de 21 anos

db.estudantes.find( {titor: "Juan Torre", idade: {$lt: 21}})

Exercicio 3: Filtra os estudantes que sexan do titor Jose Sánchez ou teñan 23 anos ou máis anos


                            db.estudantes.find( {
                                $or: [
                                    {titor: "Jose Sánchez"}, {idade: {$gte: 23}}] })
                        

Actualización (UDPATE)

updateOne

db.estudantes.updateOne(filtro, actualizacion, opcións)

Operador $set

{$set: {...} }
                    Muda ou engade valores

Exemplo $set: Engadir curso actual


                        db.estudantes.updateOne({nome: 'Luis'},
                            {$set: {'Curso': '2022/2023'}})
                    

Operador $push

{$push: {...} }
                    Engade un elemento a un array (ou crea o array co elemento)

Exemplo $push: Engadir un módulo


                        db.estudantes.updateMany({nome: 'Luis'}, 
                            {$push: {'modulos': 'FOL'}})
                    

pop

Quita un elemento dun array por posición


                        db.estudantes.updateMany( { },
                            { $pop: { modulos: 1 } }) 
                    
  • 1 ⇒ O último elemento do array.
  • -1 ⇒ O primeiro elemento do array.

pull

Borra dun array tódolos valores que cumplen unha condición.

Sintaxe


                        { $pull: { campo1: ,
                             campo2: , ... } }
                    

Exemplo

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" } } )

unset

Quita un campo dos documentos.


                        db.estudantes.updateMany(
                            { },
                            { $unset: { curso_academico: "" } }
                        )
                    

Opción: upsert

Inserta un documento cos datos se non atopa un.
db.estudantes.updateOne(
                        {nome: 'Alumno de Proba'}, 
                        {$set: {email: 'noreply@local'}}, 
                        {upsert:true} )

findAndModify()

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})
                    

updateMany()


                        use alumnado
                        db.estudantes.updateMany({},
                            {$set: {'curso_academico': '2022/2023'}})
                    
  • Se updateMany falla, debemos executalo de novo para que acabe porque non desfai os cambios (rollback).
  • Non cumpre o principio de illamento (os cambios son visibles a medida que se actualizan)

Cambiando documentos de sitio


                        db.colecion.replaceOne(filtro, reemplazo, opcións)
                    Útil xa que mantén o mesmo _id mudando o resto de datos dunha vez

Borrado (DELETE)

Borrado (DELETE)


                        db.coleccion.deleteOne/deleteMany(filtro, opcións)
                        db.collection.findOneAndDelete()
                        db.collection.bulkWrite()
                    

deleteOne()


                        db.estudantes.deleteOne({nome: 'Luis'})
                    

deleteMany()


                        db.estudantes.deleteOne({curso_academico: '2021/2022'})
                    

Aggregate ("JOIN")

Consultas con aggregate

A través dunha serie de procesos conectados entre si (agregation pipeline) os datos poden pasar por operacións (unha cada vez) que:

  • Filtren
  • Ordeen
  • Agrupen
  • Transformen

Sintaxe aggregate()


                    db-colecion.aggregate( [
                        {$stage_name: { expresión } },
                        {$stage_name: { expresión } }
                    ])

Exemplo

Da rexión 15, contar cantos datos ten de cada provincia:
                        db.coviditalia.aggregate( [
                            { $match : {"codice_regione": 15}},
                            { $group: { 
                                _id: "$codice_provincia", 
                                total_provincias: {$count:{}} }
                            }
                        ])
                    

Exemplo

Da rexión 15, contar cantos datos ten de cada provincia:
                        db.coviditalia.aggregate( [
                            { $match : {"codice_regione": 15}},
                            { $group: { 
                                _id: "$codice_provincia", 
                                total_provincias: {$count:{}} }
                            }, {$limit: 5}
                        ])
                    

Operadores (hai moitos...)

  • $match — Filtra os datos (sintaxe de find).
  • $group — Agrupa os documentos.
  • $sort — Ordea según criterio.
  • $project — Campos a amosar (última fase).
  • $set
  • $count
  • $out — Mete elementos resultante nunha colección nova.
  • $concat
  • $lookup
  • $unwind

Exemplo

Amosar as claves: data, estado, idrexion e nomerexion da 15:
                        db.coviditalia.aggregate( [
                            { $match : {"codice_regione": 15}},
                            { $project : {
                                data: 1, 
                                estado: "$stato", 
                                idrexion: "$codice_regione", 
                                nomerexion: "$denominazione_regione"}}
                        ])
                    

$out — Almacenar resultados nunha colección


                    db.coviditalia.aggregate( [
                        { $match : {"codice_regione": 15}},
                        { $project : {
                            data: 1, 
                            estado: "$stato", 
                            idrexion: "$codice_regione", 
                            nomerexion: "$denominazione_regione"}}, 
                        {$out: "rexions_en_galego"}
                    ])

Exercicio proposto

Almacenar (empregando aggregate e pipelines) os nomes das etiquetas da colección coviditalia en galego na colección: covidit-traducido.

Boas prácticas

  • Filtrar canto antes ($match) para reducir o número de documentos a procesar.
  • Tratar de empregar $project o máis tarde posible.
  • Cando empreguemos $out, poñelo ao final.

Subdocumentos

  • Notación punto: Documentos uns dentro doutros
  • Exemplos

Transaccións

Transacción clásica ACID

Transacción ACID

updateOne() é transacción ACID?


                        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.

Ollo coas transaccións!

  • Estamos a bloquear os documentos implicados. Isto aumenta a latencia e diminúe o rendemento.
  • Hai que empregar transaccións só cando é absolutamente necesario.
  • Por defecto unha transacción ten un tempo máximo de 1 minuto tras a primeira escritura.
  • Só funcionan nos servidores configurados como «replica set» e non «standalone»

Exemplo dunha transacción


                        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».

Transaccións


                        const asesion = db.getMongo().startSession()
                        asesion.startTransaction()
                        const ops = 
                            asesion.getDatabase('alumnado').getCollection('estudantes')
                    

Confirmar


                        asesion.commitTransaction()
                    

Rexeitar


                        asesion.abortTransaction()
                    

Transacción en MongoDB

Transacción MongoDB (Atlas)

Índices

### Que son os índices? - Estruturas de datos que almacenan unha pequena porción dos datos da colección dunha forma fácil (moi rápida) de percorrer. ### Que vantaxas teñen? - Evitan ter que escanear documento a documento (**collection scan**). - Engaden velocidade. - Ordean os datos referidos ascendente o descendentemente.
Esquema do funcionamento dos índices
### Creación dun índice db.collection.createIndex( { name: -1 } ) - O número indica a ordenación de datos ascendente (1) ou descendente (-1) - Por defecto créase índice por defecto na "columna" **_id** - Tamén se poden crear índices compostos (de dúas ou máis claves)

Nome por defecto do índice

Nomes dos índices e a dirección separados por _

Exemplo:

{nome : 1, apelidos: -1}

nome_1_apelidos-1

Creación dun índice cun nome

db.estudantes.createIndex(
                        { apelidos: 1, expediente: -1 } ,
                        { name: "Notas e apelidos" } )
                        

Ver os índices dunha colección

db.estudantes.getIndexes()
### Tipos de índices - Simples. - Compostos (máis dunha clave, cada unha ordenada como se queira). - Multiclave (asociados a un array). - Xeoespaciais. - De búsqueda de texto. - Hashed. - Clustered.
### Propiedades que poden ter - **Únicos (UNIQUE)**: Rexeitan valores duplicados. - **Parciais (PARTIAL)**: So para algúns documentos que cumplan unhas propiedades. - **Selectivos/Dispersos (Sparse)**: Só para os documentos que teñan a clave de índice. - **TTL**: Para borrar documentos co tempo (útil en datos xerados por máquinas) - **Agochados (HIDEN)**: Existen pero non se empregan. Permiten avaliar o impacto de quitalos
### Cotexo de datos (Data collation) - Os índices dependen do idioma para a ordenación. - Regras de acentuación, maiúsculas, minúsculas etc afectan. - Exemplos: Idioma fracés, español ou caracteres en cirílico (ou mezcla).

Creando índice con cotexo de idioma

Creamos o índice:
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"})

Búsqueda

Índice de búsqueda.

  • É unha búsqueda por relevancia.
  • O índice indica como debería facerse a busca

Índice de BBDD

  • Fai as consultas a esta búsqueda máis eficientes

Índice de búsqueda

Dynamic Mapping

  • Por defecto. A máis rápida de configurar.
  • Empréganse tódolos campos agás: Booleans, objectIds e timestamps.
  • Baseada en: Apache Lucene

Búsquedas con Apache Lucene


                        {
                            "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
                        

Índice Apache Lucene


                        atlas clusters search indexes list \
                            --clusterName myAtlasClusterEDU \
                            --db sample_supplies --collection sales
                        

                        mongosh -u myAtlasDBUser -p myatlas-001 \
                            $MY_ATLAS_CONNECTION_STRING/sample_supplies
                        

Empregando índice en agregación


                            db.sales.aggregate([
                            {
                                $search: {
                                index: 'sample_supplies-sales-dynamic',
                                text: {
                                    query: 'notepad', path: { 'wildcard': '*' }
                                } } },
                                {
                                    $set: {
                                        score: { $meta: "searchScore" }
                                    }
                                }
                                ])
                        

Índice de búsqueda

Static Indexing

Os campos sobre os que se efectúa la búsqueda son os mesmos.

Índices de BBDD para busca de texto

Creación cun so campo

db.estudantes.createIndex({titor: "text"})

Buscar empregando o índice de búsqueda

db.estudantes.find({$text:{$search:"Sánchez"}})

Índices compostos de busca de texto

Crear o índicedb.estudantes.createIndex({titor: "text", apelidos: "text"})
Empregalodb.estudantes.find({$text:{$search:"Sánchez"}})

Índices ocultos

Comportamento dos índices ocultos

Están agochados do planificador, pero aínda así:
  • Se ten unha restrición UNIQUE, siguea aplicando.
  • Se o índice é de tipo TTL, o índice aínda fai expirar os documentos.
  • Son visibles en: listIndexes e db.acolleccion.getIndexes().
  • Actualízanse coas operacións de escritura (siguen consumindo espacio e memoria)
  • Inclúense en: db.collection.stats() e $indexStats.
  • Agochar un índice ou amosar un índice agochado resetea as súas estatísticas ($indexStats).
  • Agochar un índice oculto ou amosar un índice non oculto, non resetea as estatísticas.

Restricións

  • Para agochar un índice debes ter o axuste: featureCompatibilityVersion establecido a 4.4 ou maior.
  • Sen embargo, unha vez agochado o índice, este permanece oculto aínda que poñas featureCompatibilityVersion a 4.2.
  • Non podes agochar o índice _id.
  • Non podes empregar cursos.hint() nun índice agochado.

Crear un índice oculto


                        db.estudantes.createIndex(
                           { apelidos: 1 },
                           { hidden: true }
                        );
                        

Agochar un índice

Consideramos que temos creado o índice así:

db.estudantes.createIndex( { apelidos: 1, nome: 1 } );

Opción 1: Co nome directamente

db.estudantes.hideIndex( "apelidos_1_nome_1" ); 

Opción 2: Especificando o índice completo

db.estudantes.hideIndex( { apelidos: 1, nome: 1 } );

Amosar un índice oculto

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" );

explain() — Usamos índice?


                            db.coviditalia.explain().find({codice_regione: 15})
                        
Debemos mirar no winningPlan o valor de stage
  • IXSCAN: Empregamos índice. Indica cal.
  • COLLSCAN: Non empregamos índice ningún.
  • FETCH: Os documentos lense dende a colección
  • SORT: Os documentos ordénanse na memoria.

Exercicio

Na BBDD covid, na colección coviditalia, crea un índice por «data» e «denominazione_regione».

                        db.coviditalia.createIndex( 
                            "data": 1, "denominazione_regione": 1 );

Miscelánea

Nivel pro+

Monitorización na web

Servizo de MongoDB que nos ofrece visualizar e monitorizar a nosa BBDD dende a súa web (empregará as nosas estatísticas para mellorar os seus produtos).
Activar o servizo
                            db.enableFreeMonitoring()
                        
Desactivar o servizo
                            db.disableFreeMonitoring()
                        

Telemetry

Envía a MongoDB datos anónimos estatísticos para mellorar os seus produtos.
Desactivar telemetría
                                disableTelemetry()
                            
Activar telemetría
                                enableTelemetry()
                            

Estatíscas interesantes

Teñamos activas ou non as opcións anteriores, poderemos ver estatísticas sobre a BBDD e cada colección.

Ver estatísticas da BBDD

database1> db.stats()

Ver estatísticas da coleccion «estudantes»


                            db.estudantes.stats()
                        

Modos de funcionamento de MongoDB

  • Standalone server
  • Replica sets
  • Sharded clusters

MongoDB Shell

É unha contorna REPL (Read-Evaluate-Print-Loop) de Node.js, que nos dará acceso con código JavaScript a:
  • Variables.
  • Funcións.
  • Estruturas: Condicionais, iterativas (bucles).
  • Outros mecanismos de control de fluxo.

Código Javascript na consola MongoSH


                            const artigosArray =
                                ['auga', 'pan', 'leite', 'ovos'];
                            const mercaBucle=
                                (array) => array.forEach(
                                    artigo => console.log(artigo)
                                );
                            mercaBucle(artigosArray);
                        

Conexión cunha URL

Útil se empregamos un servizo gratuito (ou de pago) externo ou se configuramos a nosa BBDD en modo multi-servidor.

                        mongosh "mongodb+srv://host-ou-servidor/BBDD" \
                            --apiVersion 1 --username O-MEU-USUARIO

Compass

É unha GUI (Graphical User Interface) que nos permite lanzar consultas (queries) e analizar os datos. Tamén nos facilita crear os pipelines de agregación.

Exercicio

Modelado de datos

Novo paradigma NO-SQL

Modelando relaciones

  • Embebidas (subdocumentos)
  • Por referencia (cun _id)

Máximas

  • Estruturar os datos segundo consulta ou modifica a túa aplicación
  • Principio: "Os datos aos que accedemos xuntos, deberían gardarse xuntos"

DATOS EMBEBIDOS

Problemas/Desvantaxes:

  • Podemos crear documentos moi grandes.
  • Os documentos grandes deben ser lidos completamente en memoria, o que pode afectar ao rendemento.
  • Se engadimos datos e máis datos creamos o que se chama «Unbounded documents» que poden exceder o límite máximo de 16MB dun documento BSON.

Son antipatróns no esquema:

  • Documentos excesivamente grandes.
  • Unbounded documents (ilimitados/sen freo).

DATOS POR REFERENCIA

Requiren:

  • Enlazado e Normalización de datos.

Vatanxes:

  • Evitan duplicación.
  • Diminuen o tamaño dos documentos.

Desvantaxes:

  • Lemos datos de varias coleccións (ou varias veces) [JOIN]
  • Ten un impacto no rendemento:
    • Require recursos extra.
    • Ten impacto na velocidade de lectura.
### Manual - https://www.mongodb.com/docs/manual ### JSON para probas (API REST) - https://dummyjson.com/ - https://github.com/Ovi/DummyJSON - https://api.sampleapis.com/fakebank/accounts
QR materiales

Jose Sánchez

Errare humanum est, sed perseverare diabolicum
Se atopas erros, envíame un correo a: