Introducció a MongoDB

De wikijoan
Salta a la navegació Salta a la cerca

Introducció

MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.

Bases de dades NoSQL a la Viquipèdia:

Instal·lació

NOTA: primer de tot heu de provar en la línia de comandes:

$ mongo

per comprovar si ja ho teniu instal·lat.

Manera oficial d'instal·lar a Linux:

Manera ràpida:

$ sudo apt install mongodb

Després de la instal·lació tenim:

$ whereis mongo
mongo: /usr/bin/mongo /usr/share/man/man1/mongo.1.gz

ls /usr/bin/mongo
/usr/bin/mongo

$ ls /usr/bin/mongo*
/usr/bin/mongo	      /usr/bin/mongofiles    /usr/bin/mongos
/usr/bin/mongod       /usr/bin/mongoimport   /usr/bin/mongostat
/usr/bin/mongodump    /usr/bin/mongoperf     /usr/bin/mongotop
/usr/bin/mongoexport  /usr/bin/mongorestore

Components principals:

  • bin/mongod - The database process. -> el servidor, el motor
  • bin/mongos - Sharding controller. -> eina de replicació
  • bin/mongo - The database shell (uses interactive javascript).

Ús bàsic de MongoDB

La database està formada per col.leccions (podem pensar-ho com a taules). I les col.leccions estan formades per Documents (podem pensar-ho com a files). Aquests Documents al final seran objectes. Aquests objectes es representen en JSON (Javascript Object Notation).

Això és un objecte JSON (està entre claus): { "name":"Joan", "cognoms":"Quintana Compte", "email": ["joanqc@gmail.com", "jquintana@jaumebalmes.net"], "telefon": "636 51 77 85" }

És un conjunt de parelles nom:valor. El valor del camp nom és un array (va amb claudàtors), i té dos elements.

Quan acabem d'instal·lar tenim la base de dades test, i no té cap col·lecció:

$ mongo

> db //per defecte estem connectats a la base de dades test
test
> show collections
> 

Creo una col.lecció students (si no existeix, es crea). Sobre la col.lecció students, existeix l'operació insert, per inserir documents. Hem de passar com a argument el document que volem inserir. I el document l'hem de passar en format JSON.

> db.students.insert({"name":"Joan", age:25})
WriteResult({ "nInserted" : 1 })

Ara ja tenim una col·lecció i una taula:

> show collections
students

> show tables
students

Això és un recordatori de què les col.leccions serien com les taules.

Per recuperar la informació que hem inserit:

> db.students.find()
{ "_id" : ObjectId("6082d776a8d8f2ae16ba2bc8"), "name" : "Joan", "age" : 25 }

o millor, per veure bé l'estructura de l'objecte:

> db.students.find().pretty()
{
	"_id" : ObjectId("6082d776a8d8f2ae16ba2bc8"),
	"name" : "Joan",
	"age" : 25
}

L'estructura és dinàmica, ara creo un document amb una altra estructura.

> db.students.insert({"name":"Pere", "cognoms":"de la Cullera", age:5})

> db.students.find().pretty()
{
	"_id" : ObjectId("6082d776a8d8f2ae16ba2bc8"),
	"name" : "Joan",
	"age" : 25
}
{
	"_id" : ObjectId("6082d98fa8d8f2ae16ba2bc9"),
	"name" : "Pere",
	"cognoms" : "de la Cullera",
	"age" : 5
}
> db.students.count()
2

Fitxer de configuració:

$ nano /etc/mongodb.conf 

Veiem en el fitxer de configuració que els datafiles estan a /var/lib/mongodb/:

$ cd /var/lib/mongodb/
$ ls
collection-0--1209326169773908654.wt  index-5--1209326169773908654.wt
collection-0--2857307013423014183.wt  index-6--1209326169773908654.wt
...

Si inspeccionem aquests fitxers (binaris, podem utilitzar cat), podem veure les nostres dades.

Veure que té una interfície de xarxa TCP, pel port 27017. Formes alternatives de connectar-se:

  • mongo test
  • mongo localhost/test
  • mongo localhost:27017/test

Hi ha altres bases de dades:

> show dbs
admin    0.000GB
config   0.000GB
local    0.000GB
product  0.000GB
test     0.000GB

Podem canviar a la base de dades product:

> use product
switched to db product
> show collections
products
> db.products.find()
{ "_id" : ObjectId("5ccb205c7740f0280ee2d277"), "prod_ref" : "ref12", "prod_name" : "GBA", "prod_desc" : "Game Boy Advance 1994", "prod_price" : 88, "updated_at" : ISODate("2019-05-02T16:52:44.146Z"), "__v" : 0 }
{ "_id" : ObjectId("5ccb2a4b7740f0280ee2d278"), "prod_ref" : "34", "prod_name" : "sdf", "prod_desc" : "sdf desc", "prod_price" : 34, "updated_at" : null, "__v" : 0 }
...

En la interfície de Mongo podem utilitzar Javascript:

> use test
> for (var i=0; i<=7000; i++) {
   db.logs.insert({"_id": i, "ranking":Math.random()});
}

> db.logs.find()
{ "_id" : 0, "ranking" : 0.48693637494310693 }
{ "_id" : 1, "ranking" : 0.9805899420487253 }
{ "_id" : 2, "ranking" : 0.12136667863678441 }
{ "_id" : 3, "ranking" : 0.7458044616524797 }
...

Per esborrar aquests valors:

> db.logs.drop()
true

> db.logs.find()
>

Anem a inserir uns quants estudiants més:

> use test

db.students.insert({"name":"Jordi", age:20})
db.students.insert({"name":"Martí", age:18})
db.students.insert({"name":"Maria", age:16})
db.students.insert({"name":"Rita", age:14})
db.students.insert({"name":"Clara", age:12})
db.students.insert({"name":"Pau", age:10})
db.students.insert({"name":"Jeroni", age:12})
db.students.insert({"name":"Rosa", age:14})
db.students.insert({"name":"Montserrat", age:16})
db.students.insert({"name":"Anna", age:18})
db.students.insert({"name":"Miquel", age:20})

> db.students.find()

i anem a fer les operacions bàsiques. Ja sabem fer inserts, anem a fer una lectura (select) una mica més interessant, un update i un delete.

db.students.find({ age: { $gt:14} }).sort({age:1})
{ "_id" : ObjectId("6082dfd0f42d8640eeeff842"), "name" : "Maria", "age" : 16 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff848"), "name" : "Montserrat", "age" : 16 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff841"), "name" : "Martí", "age" : 18 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff849"), "name" : "Anna", "age" : 18 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff840"), "name" : "Jordi", "age" : 20 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff84a"), "name" : "Miquel", "age" : 20 }
{ "_id" : ObjectId("6082d776a8d8f2ae16ba2bc8"), "name" : "Joan", "age" : 25 }

> db.students.find({ age: { $gt:14} }).sort({age:1}).count()
7

Les select poden arribar a ser molt complicades. Per exemple, també existeixen funcions d'agregació (equivalent al group by de SQL).

db.students.updateOne(
   { name: "Miquel" },
   {
     $set: { age: 22 }
   }
)

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.students.find({ age: { $eq:22} }).sort({age:1})
{ "_id" : ObjectId("6082dfd0f42d8640eeeff84a"), "name" : "Miquel", "age" : 22 }
db.students.updateMany(
   { age: 18 },
   {
     $set: { age: 22 }
   }
)
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

> db.students.find({ age: { $eq:22} }).sort({age:1})
{ "_id" : ObjectId("6082dfd0f42d8640eeeff841"), "name" : "Martí", "age" : 22 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff849"), "name" : "Anna", "age" : 22 }
{ "_id" : ObjectId("6082dfd0f42d8640eeeff84a"), "name" : "Miquel", "age" : 22 }

Per esborrar:

> db.students.remove( { age: { $lt: 14 } } );
WriteResult({ "nRemoved" : 4 })

Connexió amb diferents llenguatges de programació

PHP

$ sudo apt-cache search php | grep mongo
php-mongodb - MongoDB driver for PHP

$ sudo apt-get install php-mongodb

Treiem l'exemple bàsic de:

script php_mongo_example.php:

<?php
	//connexió
	$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

	echo "llistem les bases de dades:\n";
	$listdatabases = new MongoDB\Driver\Command(["listDatabases" => 1]);
	$res = $mng->executeCommand("admin", $listdatabases);
	$databases = current($res->toArray());
	foreach ($databases->databases as $el) {
	    echo $el->name . "\n";
	}

	// estudiants
	echo "\nllistem els estudiants: \n";
	$query = new MongoDB\Driver\Query([]); 
	$rows = $mng->executeQuery("test.students", $query);
	foreach ($rows as $row) {
		echo "$row->name : $row->age\n";
	}
?>
$ php php_mongo_exemple.py

llistem les bases de dades:
admin
config
local
test

llistem els estudiants: 
Joan : 25
Pere : 5
Jordi : 20
...

Python

$ sudo apt-cache search python | grep mongo
...
python3-pymongo - Python3 interface to the MongoDB document-oriented database
...

$ sudo apt-get install python3-pymongo

script python_mongo_exemple.py:

import pymongo
from pymongo import MongoClient

client = MongoClient()
db = client.test

students = db['students']
for student in students.find():
	#print(student)
	for key, value in student.items():
		#print (key, value)
		if (key=='name'):
			nom = value;
		if (key=='age'):
			edat = value
			print(nom, ': ', edat)
$ python3 python_mongo_exemple.py

Joan :  25.0
Pere :  5.0
Jordi :  20.0
...

NodeJS

$ sudo apt-cache search node | grep mongo
node-mongodb - official MongoDB driver for Node.js

$ sudo apt-get install node-mongodb

Hem agafat l'exemple bàsic de:

script node_mongo_exemple.py:

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";

MongoClient.connect(url, function(err, db) {
	if (err) throw err;
	var dbo = db.db("test");

	dbo.collection("students").find().toArray(function(err, result) {
		if (err) throw err;
		//console.log(result);
		for (let i=0;i<result.length;i++) {
			console.log(result[i].name + ": " + result[i].age);
		}
	});
	
	db.close();

});
$ node node_mongo_exemple.js

Joan: 25
Pere: 5
Jordi: 20
...

Pots seguir un tutorial de MongoDB i NodeJS a:

BASH

Bash no és un llenguatge de programació. Però podem executar Mongo des de la línia de comandes com havíem fet més amunt.

I amb l'opció --eval podem executar una comanda:

$ mongo --eval 'db.students.find().pretty();' test

Qualsevol script dels que hem vist (PHP, Python, NodeJS) el podem integrar dins dels nostres scripts Bash.

Però recorda que tant PHP, Python o NodeJS són llenguatges per fer scripts ells mateixos.



creat per Joan Quintana Compte, abril 2021