--- title: MongoDb tags: daw, DAM --- ![](https://i.imgur.com/uTH7Ccw.png) # MongoDB. [Vincle a font en MarkDown](https://hackmd.io/@JdaXaviQ/BkN70S8FF) Link a paquets d'Ubuntu: [mongosh_1.7.0_amd64.deb](https://downloads.mongodb.com/compass/mongodb-mongosh_1.7.0_amd64.deb) [mongodb-org-server_5.0.4_amd.deb](https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/5.0/multiverse/binary-amd64/mongodb-org-server_5.0.4_amd64.deb) Link a la documentació oficial: [Documentació de MongoDB](https://docs.mongodb.com/manual/) Curs: [Using MongoDB with Python](https://learn.mongodb.com/learning-paths/using-mongodb-with-python) Link a la documentació de les dades de prova: [Sample DataSet](https://www.mongodb.com/docs/atlas/sample-data/) MongoDb, nom que prové de les paraules angleses hu***mongo***us(*Enorme*) i ***Database*** (*Base de dades*), és una base de dades de codi obert orientada a documents. Una forma pragmàtica de definir què és un motor de base de dades orientat a documents és veure'l com un motor de base de dades que treballa amb JSONs. Cada JSON és un __document__ i els podem agrupar en __col·leccions__ (anàlogues a les taules) de documents afins. Segons els creadors de MongoDB, els avantatges són: * Un document pot ser la serialització directa d'un objecte de la nostra aplicació. * Els documents __incrustats (embedded)__ i els arrays, redueixen la necessitat de joins costosos. * L'esquema dinàmic permet el polimorfisme fluid. > Tots els documents emmagatzemats a una col·lecció de MongoDB contenen el camp '\_id'. El camp __\_id__ ha de ser únic i funciona de manera anàloga a les claus primàries de les taules de les bases de dades relacionals. Si un document no declara el camp \_id, el motor de Mongo l'afegeix de forma automàtica. ## Algunes comandes útils per començar: * Llistar les bases de dades existents: db.adminCommand({listDatabases: 1}) * Utilitzar una base de dades: use <nom_de_la_base_de_dades> * Mostrar les col·leccions de la base de dades actual: show collections ## Operacions CRUD amb MongoDB. ### Create (Insert) Es poden insertar documents de forma individual o en grups. * db.\<collection>.insertOne({ < contingut del document > }) * db.\<collection>.insertMany([ { < un document > }, { < altre document > } ]) ### Característiques dels inserts: 1. Si la col·lecció no existeix es crea automàticament. 2. Tots els documents han de tenir un camp \_id que actúa com a clau primaria. Si un document no conté un camp \_id, se li crea automàticament. 3. Les operacions d'insert són atòmiques a nivell de document, si necessitem atomicitat a nivell d'instrucció, hem de recòrrer a les transaccions. ### Read (Find) * db.\<collection\>.find() ``` db.movies.find() ``` És l'equivalent a: ```sql= SELECT * FROM movies; ``` * db.\<collection\>.find({\<filtre\>}) ``` db.movies.find( { "title": "Titanic" } ) ``` És l'equivalent a: ```sql= SELECT * FROM movies WHERE title = 'Titanic'; ``` Especificar més d'un camp comporta una 'AND' implícita: ``` db.movies.find( { countries: "Mexico", "imdb.rating": { $gte: 7 } } ) ``` És equivalent a: ```sql= SELECT * from movies where countries='Mexico' AND actor = 'Miguel Veracruz'; ``` #### Operadors de queries: MongoDB posa a la nostra disposició un conjunt d'operadors de queries per a facilitar-nos les búsquedes de documents [query operators](https://docs.mongodb.com/manual/reference/operator/query/#query-selectors) ``` db.movies.find( { rated: { $in: [ "PG", "PG-13" ] } } ) ``` És l'equivalent a: ```sql= SELECT * FROM movies WHERE rated in ('PG', 'PG-13'); ``` ### Update * db.\<collection\>.updateOne() * db.\<collection\>.updateMany() * db.\<collection\>.replaceOne() [Operadors de les operacions d'update](https://docs.mongodb.com/manual/reference/operator/update/) ### Delete Les operacions d'esborrat es poden realitzar amb una sintaxi similar a les consultes i les comandes: * db.\<collection\>.deleteOne() * db.\<collection\>.deleteMany() Si passem un filtre buit a la comanda db.\<collection\>.deleteMany({}), s'esborren tots els elements de la col·lecció. ## MongoDb Atlas Atlas és el servei de MongoDb per tenir una base de dades SaaS (Software as a Service). Utilitza els núvols d'Azure, Google i AWS i ens permet triar el que s'avingui millor a les nostres preferències. Atlas ens permet utlitzar un cluster compartit per realitzar proves. Durant aquesta UF crearem un per a cadascú de nosaltres i el farem servir per a treballar els continguts del mòdul. ### Creant i desplegant un cluster Atlas Primer de tot hem de crear un compte a MongoDB Atlas, la forma més senzilla és identificar-se amb el correu coorporatiu de l'institut. A continuació haurem de crear un nou Deployment (desplegament). ![imagen](https://hackmd.io/_uploads/SyFdwkbc6.png) Per motius obvis,seleccionarem la opció gratuïta. ![imagen](https://hackmd.io/_uploads/SJpEdJb9T.png) Com que nosaltres no hem de patir massa per la seguretat, potser és una bona idea afegir la xarxa 0.0.0.0/0 a la llista de xarxes permeses i d'aquesta forma podrem accedir al nostre clúster des de qualsevol lloc. També és útil recordar que quan connectem des de les nostres app python amb Atlas, el password s'ha d'enviar URL encoded, per aquesta raó hem de seleccionar els caracters que posem al nostre password per a no haver de fer 'coses rares' a l'hora de declarar la nostra connection string. Veure el següent [link](https://www.mongodb.com/docs/atlas/troubleshoot-connection/#special-characters-in-connection-string-password) de la documentació oficial de MongoDB. ![imagen](https://hackmd.io/_uploads/rkzmYy-56.png) ## MongoDB i Python ### Amb el connector pymongo Podem instal·lar el connector de Mongo per a python amb la següent comanda: ``` sudo apt install python3-pymongo ``` #### Conectant la nostra aplicació python3 a MongoDB Atlas. ```python= #!/usr/bin/python3 # -*- coding= utf-8 -*- import pymongo # install with $ python3 -m pip install pymongo def connect(): """ connecta a la nostra base de dades MongoDb a Atlas. """ pwd = "password" user = "user" cluster = "cluster0.b30j44t" uri = "mongodb+srv://" + \ user + ":" + pwd + \ "@" + cluster + ".mongodb.net/?retryWrites=true&w=majority" return pymongo.MongoClient(uri) def list_databases(mongo_client): """ imprimeix per pantalla el llistat de bases de dades disponibles. """ for db_name in mongo_client.list_database_names(): print(db_name) def main(): mongo = connect() list_databases(mongo) mongo.close() if __name__ == "__main__": main() ``` #### Creant la nostra propia base de dades. No necessitem cap comanda especial per a crear una base de dades nova a MongoDB, només hem de seleccionar el nom de la base de dades que volem crear i inserir un nou document a qualsevol nom de colecció que també es crearà automàticament. ```python= def main(): database_name = 'DAM2_M6' mongo = connect() db = mongo[database_name] db.deleteme.insert_one({"foo": "bar"}) list_databases(mongo) db.drop_collection('deleteme') mongo.close() ``` De manera anàloga una base de dades sense coleccions o sense documents no serà visible. ## Estructura de dades: Podem contemplar dues estratègies diferents a l'hora de relacionar documents quan la cardinalitat és 1:1 o 1:N. 1. Una primera opció és utilitzar documents encastats. 2. L'altra opció és relacionar col·leccions mitjançant 'clau foranes' de manera similar a com ho fem als SGBD relacionals. ### Avantatges i inconvenients dels documents encastats. * #### Avantatges: * Millor rendiment: Els documents incrustats permeten accedir a tota la informació relacionada en una única consulta, la qual cosa millora el rendiment al reduir la necessitat de realitzar múltiples consultes per obtenir dades relacionades. Permet desar junta la informació que es consumeix al mateix temps. * Model més senzill: La estructura dels documents encastats tendeix a ser més senzilla i més intuïtiva. Les dades relacionades estan encapsulades dins del mateix document, facilitant la comprensió i el modelatge de dades. * #### Inconvenients: * Redundància de Dades: Algunes dades poden repetir-se en diversos documents, la qual cosa pot portar a inconsistències si no s'actualitzen de manera coherent a tots els llocs on estan incrustades. * Creciment de la Mida del Document: A mesura que els documents encastats creixen amb la incorporació de més dades, poden afectar el rendiment, especialment en conjunts de dades més grans. Fins i tot, hi ha el perill s'assolir el __tamany màxim de document__. * Dificultats amb Actualitzacions Freqüents: Actualitzar informació en documents encastats pot ser més complex, especialment quan es tracta de dades que s'actualitzen amb freqüència o que tenen dependències en altres documents. * #### Bones pràctiques en l'ús de documents encastats: * Ús en conjunt de dades petites i estables: Els documents incrustats són més adients per a conjunts de dades petits i relativament estables, on la redundància de dades no genera problemes significatius de consistència. * Optimització de lectura: Utilitza documents encastats quan es necessita optimitzar les operacions de lectura i recuperar dades relacionades de manera eficient. * Aniuar les dades de forma lògica: Encasta documents quan les dades tenen una relació lògica i quan és poc probable que canviïn amb freqüència. ### Avantatges i inconvenients de les relacions de col·leccions. * #### Avantatges * Evita la Redundància: Les relacions de col·leccions eviten la redundància de dades ja que cada peça d'informació es guarda en una única ubicació, millorant la consistència de les dades. * Escalabilitat més gran: Les relacions de col·leccions són més eficients per manejar conjunts de dades més grans, ja que eviten el creixement excessiu dels documents. * Actualitzacions Senzilles: Actualitzar informació és més senzill ja que no cal actualitzar múltiples documents com en el cas dels documents incrustats. * #### Inconvenients * Consultes Més Elaborades: Les consultes poden ser més complexes i requerir l'ús d'operacions de cerca o d'agregació per recuperar dades de col·leccions relacionades. * Rendiment potencialment menor en consultes complexes: Algunes consultes poden ser menys eficients, especialment aquelles que involucren la unió de dades de múltiples col·leccions. * #### Bones Pràctiques * Ús en Conjunts de Dades Grans: Les relacions de col·leccions són més adequades per a conjunts de dades grans, on la consistència i la gestió eficient són prioritàries. * Manteniment de la Consistència: Utilitza relacions de col·leccions quan la consistència de les dades és crucial i cal evitar duplicacions. * Optimització en Consultes d'Agregació: Enfoquem en l'optimització de consultes d'agregació quan es fan servir relacions de col·leccions per millorar el rendiment. # BSON (Binary JSON) BSON és el format amb el que MongoDB desa les dades. És una serialització binària d'un superconjunt del format JSON. No és la única forma de serialitzar documents JSON en format binari, Google en té una altra anomenada [_Protocol Buffers_ (**protobuf**)](https://github.com/protocolbuffers/protobuf). Segons la mateixa [documentació oficial de BSON](https://bsonspec.org/), el format ha estat dissenyat per seguir 3 característiques: 1. **Lleuger**: Intentar que les dades ocupin el mínim espai possible, és important per a qualsevol format de representació de dades, especialment quan s'utilitza a través de la xarxa. 2. **Explorable amb facilitat**: BSON està dissenyat per poder explorar i recòrrer les dades amb facilitat. Aquesta és una propietat vital en el seu paper com a representació de dades principal per a MongoDB. 3. **Eficient**: Codificar dades a BSON i descodificar de BSON es pot realitzar molt ràpidament a la majoria de llenguatges gràcies a l'ús de tipus de dades en C.