MongoDB és una base de dades no-SQL orientada a document.
Aquest article està orientat a la connexió a MongoDB a través de diferents llenguatges de programació.
Es recomana utilitzar una versió avançada de MongoDB. Si la versió de MongoDB és 2.x o menor, algunes eines com Robomongo o Studio 3T no ens funcionaran bé. A Ubuntu 18.04 hi ha MongoDB > 3.x, cap problema, doncs (però a Ubuntu 16.04 tenien versions 2.x i no eren viables).
Recursos:
Importa amb mongorestore
la base de dades de prova movies-mongo-dump.rar. La utilitat d'importació habitual és mongoimport
, però en aquest cas farem servir mongorestore
ja que les dades estan en format binari).
Primer cal instal·lar el //driver// tal i com s'explica a la documentació. (Adaptar aquestes ordres a la versió adequada si fos necessari: p.ex. php-dev podria ser php7.2-dev ).
Per Ubuntu LTS això funcionaria:
$ sudo apt install php-dev php-pear $ sudo pecl install mongodb
Afegim la llibreria a la instal·lació afegint a l'arxiu php.ini
:
extension=mongodb.so
Cal mirar la documentació de la llibreria.
Suposant una col·lecció bàsica com aquesta:
{ "_id" : ObjectId("5e1b40a2d7a590a8d1709ab7"), "marca" : "Renault", "model" : "Twizzy" } { "_id" : ObjectId("5e1b40add7a590a8d1709ab8"), "marca" : "Seat", "model" : "León" }
Cal mirar bé la documentació de PHP perquè hi ha diversos drivers i s'utilitzen de forma diferent. El què hem instal·lat correspon a aquesta doc: https://www.php.net/manual/es/book.mongodb.php
Aquest ens ha funcionat amb el següent exemple:
use MongoDB\Driver\Manager as MongoManager; use MongoDB\Driver\Query as MongoQuery; $mongo = new MongoManager(); $filter = []; $options = []; $query = new MongoQuery( $filter, $options ); $cotxes = $mongo->executeQuery( "prova.cotxes", $query ); foreach( $cotxes as $cotxe ) { echo $cotxe->marca." ".$cotxe->model."<br>\n"; }
Importa amb mongorestore
la base de dades de prova movies-mongo-dump.rar.
Per saber més de NodeJS mira't els apunts a nodejs_express.
Per connectar-nos disposem del Driver asíncron (mongodb) per a JavaScript. Pots instal·lar-lo amb
$ npm install mongodb
Les classes principals que utilitzarem són Cursor i Collection
Els cursors ben explicats aquí.
Per gestionar les connexions a MongoDB dins d'una aplicació web (concorrent per natura) es recomana fer 1 sola connexió per la app, i reutilitzar l'element db
en cada request. Això ens proveirà el que anomenem connection pooling. El driver és intel·ligent i sap gestionar les diverses connexions de la forma més òptima per paral·lelitzar els accessos del servidor web.
Per inicar el projecte node, crea dins d'una carpeta:
$ npm init $ npm install express body-parser ejs mongodb
Afegeix el codi a index.js i arrenca el servidor:
$ node index.js
Doc inicial sobre les collections i cursors de MongoDB.
Exmple de connexió per a una pàgina web:
// framework express var express = require('express'); // bodyparser ens permet processar variables GET i POST var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.urlencoded({ extended: false })); // per renderitzar les plantilles (render) app.set('view engine','ejs'); var mongo = require('mongodb').MongoClient; var mongoClient; // connexió a mongo i start app mongo.connect('mongodb://localhost:27017', function( err, _client ) { // si no ens podem connectar, sortim if( err ) throw err; mongoClient = _client; // si no hi ha cap error de connexió, engeguem el servidor app.listen(3000, function () { console.log('Example app listening on http://localhost:3000 !'); }); }); // view: llistat elements app.get('/', function (req, res) { var db = mongoClient.db("cotxes"); var opcions = {}; var query = {}; db.collection('cotxes').find( query, opcions ).toArray(function( err, docs ) { if( err ) { res.render( 'error', {msg:"error a la query"} ); return; } // renderitzem la plantilla q hem de crear a views/cotxes.ejs res.render( 'cotxes', {"cotxes":docs} ); }); }); // view: llistat elements en format JSON (API) app.get('/api/movies', function (req, res) { var db = mongoClient.db("video"); var fields = { _id:true, title:true, year:true }; var query = {}; var opcions = { limit:4, fields:fields }; db.collection('movieDetails').find( query, opcions ).toArray(function( err, docs ) { if( err ) { res.send( JSON.stringify( {status:"error",msg:"error a la query"}) ); return; } // transformem l'array "docs" en un string i el retornem tal qual res.send( JSON.stringify(docs) ); }); });
Visita la web amb el browser a (cal abans crear les plantilles ejs descrites més avall)
http://localhost:3000
Prova la API amb la comanda:
$ curl localhost:3000/api/movies
A aquest codi caldrà afegir les plantilles error.ejs
i cotxes.ejs
a la carpeta views
que renderitzarà finalment la llista de cotxes que ens ha retornat a docs
.
https://mongodb.github.io/node-mongodb-native/3.5/tutorials/collections/
És important remarcar que
db.collection().find()
ens retorna un Cursor. Els cursors és una mena de punter a la BD. No carreguen totes les dades en memòria.db.collection().find().toArray()
ens retorna un array amb les dades extretes. Abans de cridar toArray
hem d'estar segurs que tindrem prou memòria RAM per poder emmagatzemar les dades. Fer una query que retorni molts resultats pot ser perillós ja que podria saturar el servidor.De vegades voldrem accedir a diferents elements de la llibreria de MongoDB per a NodeJS. Per exemple, per generar ObjectIDs fes un cop d'ull a aquest codi.
Obriu-vos un compte a MongoDB Atlas que us permetrà crear un cluster MongoDB gratuït al núvol. Importeu les col·leccions d'exemple per poder fer proves.
Si busqueu com connectar al vostre cluster, us mostrarà un string del tipus:
mongodb+srv://pepe:[email protected]/mydb
… que significa que em puc connectar a l'usuari «pepe» amb password «pepe123» i accedir a la BD «mydb».
Modifiqueu el codi de l'aplicació perquè us connecti a la vostra instància Atlas. Penseu que no podeu crear un codi que contingui usuaris i contrasenyes i pujar-ho al sistema de control de versions (GitHub), ja que l'exposaríeu a altres usuaris i us hackejarien la base de dades fàcilment. Així, una bona pràctica de control de versions és posar el usuari i password del nostre cluster a les variables d'entorn, i al codi capturar-ho amb process.env.MYVAR
:
Abans d'engegar l'aplicació haureu de ajustar les variables d'entorn amb
$ export DBUSER=admin $ export DBPASS=P@ssw0rd $ node app.js
// connexió a mongo i start app var mongo = require('mongodb').MongoClient; var mongoClient; // consts const PORT = process.env.PORT || 5000 const user = encodeURIComponent( process.env.DBUSER ); const pass = encodeURIComponent( process.env.DBPASS ); var dbConStr = "mongodb+srv://"+user+":"+pass+"@cluster0-metgf.mongodb.net/grades"; mongo.connect( dbConStr, function( err, _client ) { // si no ens podem connectar, sortim if( err ) throw err; mongoClient = _client; // si no hi ha cap error de connexió, engeguem el servidor app.listen(PORT, function () { console.log('Example app listening on http://localhost:'+PORT+' !'); }); });
Aquest codi anterior captura les variables DBUSER i DBPASS de l'entorn de la shell, la qual cosa va bé, però resulta una mica incòmode ajustar les variables cada cop que engeguem la màquina. Per estalviar-nos aquest pas, podem posar les variable a l'arxiu .env
, però afegint .env
al .gitignore
per evitar que pugem aquest arxiu amb contasenyes al repositori de codi.
Utilitza el paquet dotenv de npm per carregar les variables d'entorn de l'arxiu .env
. Tindrem un arxiu '.env' com ara:
DBUSER=user DBPASS=P@ssw0rd
I podem carregar-lo tal i com diu la documentació, amb:
require('dotenv').config()
Importa amb mongorestore
la base de dades de prova movies-mongo-dump.rar.
Crea una web amb la base de dades de films que implementi: