CRUD amb MongoDB.Java per tal d’accedir a la informació de MongoDB.Segurament hagis sentit parlar de les bases de dades NoSQL (Not Only SQL). És una cosa que últimament està molt de moda en el món del desenvolupament.
Resumint les bases de dades NoSQL, difereixen en diversos punts a les bases de dades relacionals de tota la vida com són: que no fan servir SQL ja que no són bases de dades relacionals, que no es necessiten estructures fixes (taules, columnes etc.) i en general no suporten ACID (atomicitat, consistència, aïllament, durabilitat).
En el nostre cas parlarem de bases de dades documentals. Tot i que aquesta primera presa de contacte es centrarà més en les bases de dades documentals, ho farem tenint en compte que en el futur farem servir MongoDB.
MongoDB és una base de dades de documents de propòsit general de codi obert.
MongoDB (de “humongous”) és una base de dades de documents de codi obert i el líder NoSQL de base de dades, escrita en C++.
MongoDB és una base de dades de documents de codi obert que ofereix un alt rendiment, alta disponibilitat i escalat automàtic.
MongoDB és una base de dades de documents de codi obert dissenyada per facilitar el desenvolupament i escalat.
L’empresa de programari 10gen va començar a desenvolupar MongoDB el 2007 com a component d’una plataforma planificada com a producte de servei.
El 2009, l’empresa va passar a un model de desenvolupament de codi obert, amb l’empresa oferint suport comercial i altres serveis. El 2013, 10gen va canviar el seu nom a MongoDB Inc.
MongoDB és un dels populars servidors de bases de dades NoSQL utilitzats per desenvolupar aplicacions dinàmiques modernes. Fa ús de documents semblants a JSON i esquemes opcionals; objectes de dades emmagatzemats com a documents separats dins d’una col·lecció, a diferència de les files i columnes utilitzades a les bases de dades relacionals tradicionals.
MongoDB és altament escalable i flexible i ofereix consulta i indexació fàcils per als desenvolupadors. A causa de les seves capacitats d’escala horitzontal i d’equilibri de càrrega, MongoDB ha ofert als desenvolupadors els nivells més alts de flexibilitat i escalabilitat. MongoDB Atlas és un servei de bases de dades al núvol i és líder en el desenvolupament d’aplicacions modernes i pot implementar bases de dades al núvol totalment gestionades a Azure, AWS o Google Cloud.
MongoDB ofereix tant una edició comunitària que es pot descarregar i utilitzar gratuïtament com una edició Enterprise que forma part de la subscripció avançada de MongoDB Enterprise. Aquesta versió Enterprise inclou un suport complet per al vostre desplegament de MongoDB i ofereix funcions enfocades a l’empresa, com ara suport LDAP i Kerberos, xifratge en disc i auditoria.
{
nom: "John Smith",
pfxs: [“Dr.”,”Sr.”],
adreça: "10 3rd St.",
telèfons: [
{ número: "555-1212",
escriviu: "casa"},
{ número: "444-1212",
escriviu: "mòbil" }
]
}
MongoDB és una base de dades de documents de propòsit general de codi obert.
MongoDB són similars als objectes JSON. Els valors dels camps poden incloure altres documents, matrius i matrius de documents.{
_id: “123”,
title: "MongoDB: The Definitive Guide",
authors: [
{ _id: "kchodorow", name: "Kristina Chodorow“ },
{ _id: "mdirold", name: “Mike Dirolf“ }
],
published_date: ISODate(”2010-09-24”),
pages: 216,
language: "English",
publisher: {
name: "O’Reilly Media",
founded: 1980,
locations: ["CA”, ”NY” ]
}
}
MongoDB utilitza un model de dades de document i emmagatzema un format binari de documents JSON anomenat BSON.MongoDB, de manera que els documents poden variar en estructura i poden adaptar-se dinàmicament.| RDBMS | MongoDB |
|---|---|
| Database | Database |
| Table | Collection |
| Index | Index |
| Row | Document |
| Column | Field |
| Join | Embedding & Linking & $lookup |
SQL GROUP BY; i Map-Reduce per a una anàlisi complexa i local.MongoDB 5.0 és l’última versió publicada el 13 de juliol de 2021. Hi ha una sèrie de correccions fetes a partir de les versions anteriors i també algunes funcions addicionals que les podeu trobar totes a les notes de llançament oficials de MongoDB 5.0. Algunes de les característiques addicionals inclouen:
$dateAdd, $dateDiff, $dateSubtract, $getField, $rand i molts més. Consulteu la documentació.$setWindowFields que permet realitzar operacions en un interval especificat de documents d’una col·lecció, coneguda com a finestra.MongoDB utilitza JSON (o millor dit, BSON) per tractar amb documents.
Però què és exactament JSON? Mireu el següent exemple senzill:
{
"name" : "John",
"age" : 33,
"great" : true
}
Si sou un desenvolupador de JavaScript, us hauria de semblar familiar.
Un document JSON pot tenir una o més parelles clau - valor. Les claus són sempre cadenes i sempre han d’anar entre cometes (a diferència de JavaScript, on hi ha cometes de vegades opcional).
Els valors poden ser d’un dels tipus següents:
Número (Number): format de coma flotant de doble precisió, segons la implementació.Cadena (String): Unicode entre cometes dobles, amb barra invertida escapada.Booleà (Boolean): true o false.Matriu (Array): una seqüència de valors ordenada, separada per comes, tancada en quadrat claudàtors.Objecte (Object): una col·lecció de claus no ordenada i separada per comes: parells de valors tancats amb claus.null: buit.MongoDB és un sistema gestor de base de dades orientat a documents. El que vol dir, en llenguatge d’estar per casa, que el que guardem a la base de dades són documents. MongoDB guarda els documents en BSON, que no és més que una implementació binària del conegut JSON. Per tant tots els documents guardats a la base de dades es poden tractar com faríem en JavaScript. De fet, ja anirem veient que per a realitzar consultes, a la consola de MongoDB utilitzarem JavaScript.
Realment no necessiteu saber res sobre BSON per treballar amb MongoDB, així que sentiu-ho lliure d’ometre aquesta secció, però si, com jo, us pregunteu sobre el rendiment i “com coses funcionen” segueix llegint.
Un dels motius és perquè es pot escanejar ràpidament.
Tenint en compte que JSON és només una cadena, per trobar una clau específica que necessiteu escanejar cada caràcter d’aquesta cadena, fent un seguiment del nivell de nidificació, fins que trobes aquesta clau específica. Poden ser tones de dades que cal escanejar.
BSON, però, emmagatzema la longitud dels valors per tal de trobar aquesta clau específica només pot saltar els valors passats i llegir la següent clau.
http://bsonspec.org/
Un document BSON comença amb la longitud del document, en aquest cas 23 bytes. S’emmagatzemen com a nombres enters de 32 bits, little endian, de manera que "23" s’emmagatzemaria realment com \x17\x00\x00\x00.
Mentre que per a la llegibilitat vaig escriure 23, les longituds de les notes són de 4 bytes ja que són de 32 bits nombres enters.
Aleshores, per a cada clau: parell de valors, BSON especifica el tipus de valor com a clau d’un sol byte com a cadena acabada nul·la, la longitud del valor com a nombre enter de 32 bits si escau i el valor mateix.
Els documents, les matrius i les cadenes tenen una terminació nul·la.
Pregunta: Quin és el JSON corresponent per al document XML següent?
<person>
<name>John</name>
<age>25</age>
<address>
<city>New York</city>
<postalCode>10021</postalCode>
</address>
<phones>
<phone type="home">212-555-1234</phone>
<phone type="mobile">646-555-1234</phone>
</phones>
</person>
{ "name" : "John",
"age" : 25,
"address" : { "city" : "New York", "postalCode" : "10021" },
"phones" : [
{"phone":"212-555-1234", "type" : "home"},
{"phone":"646-555-1234", "type" : "mobile"}
]
}
Els documents es guarden en col·leccions, que podria assemblar-se a les taules que coneixem dels sistemes relacionals. La diferència principal és que els documents no tenen perquè tenir els mateixos camps. Potser un document tingui un camp que no existeix en un altre, i fins i tot els tipus de dades poden ser diferents.
Com es pot veure, no tenim un esquema definit, de manera que l’enfocament que utilitzarem amb MongoDB és totalment diferent al que utilitzaríem amb un RDBMS. En no existir les relacions directament, hem de pensar una mica en com anem guardar els documents per no sobrecarregar la nostra base de dades fent consultes massa grans o duplicant consultes.
Els passos següents ens guiaran sobre com podem instal·lar MongoDB 5.0 a Ubuntu 20.04
Primer hem d’importar la clau GPG pública de MongDB com es mostra a continuació:
$ wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
OK
En cas que rebeu un error en què falta gnup, podeu instal·lar-lo executant l’ordre següent i, a continuació, torneu a intentar afegir la clau.
sudo apt update
sudo apt-get install gnupg
Per poder instal·lar MongoDB amb apt, hem d’afegir el repositori MongoDB.
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
Ja hem afegit MongoDB GPG i repositori, procedim a instal·lar MongoDB. Actualitzeu primer els paquets
sudo apt-get update
sudo apt-get install -y mongodb-org
Si voleu instal·lar una versió específica de MongoDB, podeu passar la versió tal com es mostra a continuació.
sudo apt-get install -y mongodb-org=5.0.2 mongodb-org-database=5.0.2 mongodb-org-server=5.0.2 mongodb-org-shell=5.0.2 mongodb-org-mongos=5.0.2 mongodb-org-tools=5.0.2
Un cop finalitzat el procés d’instal·lació, procediu a iniciar i habilitar MongoDB.
sudo systemctl start mongod
Confirmeu que MongoDB s’està executant realment.
$ systemctl status mongod
● mongod.service - MongoDB Database Server
Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor prese>
Active: active (running) since Tue 2021-08-24 15:42:58 UTC; 11s ago
Docs: https://docs.mongodb.org/manual
Main PID: 14497 (mongod)
Memory: 61.6M
CGroup: /system.slice/mongod.service
└─14497 /usr/bin/mongod --config /etc/mongod.conf
Apr 22 13:12:27 elpuig-ubuntu systemd[1]: Started MongoDB Database Server.
Confirma la versió de MongoDB
$ mongod --version
db version v5.0.2
Build Info: {
"version": "5.0.2",
"gitVersion": "6d9ec525e78465dcecadcff99cce953d380fedc8",
"openSSLVersion": "OpenSSL 1.1.1f 21 Apr 2021",
"modules": [],
"allocator": "tcmalloc",
"environment": {
"distmod": "ubuntu2004",
"distarch": "x86_64",
"target_arch": "x86_64"
}
}
A continuació, podeu habilitar MongoDB perquè s’iniciï automàticament en reiniciar el sistema.
$ sudo systemctl enable mongod
Created symlink /etc/systemd/system/multi-user.target.wants/mongod.service → /lib/systemd/system/mongod.service.
El fitxer de configuració de MongoDB es troba a /etc/mongod.conf. Aquí trobareu les configuracions per a la ruta db, la ruta dels registres. Sempre podeu fer canvis a aquest fitxer en funció de les vostres necessitats d’instal·lació. Reinicieu el servei mongod cada vegada que feu un canvi al fitxer.
Activem l’autenticació de contrasenya de MongoDB perquè els usuaris puguin iniciar sessió amb una contrasenya per llegir o editar la base de dades. Descomenteu #security i afegiu el contingut com a continuació:
security:
authorization: enabled
Després d’això, reinicieu el servei mongod.
sudo systemctl restart mongod
Per defecte, MongoDB només es pot accedir localment. Si voleu poder accedir a la base de dades de forma remota, farem un petit canvi al fitxer de configuració per incloure l’adreça IP o el nom d’amfitrió del servidor MongoDB, tal com es mostra a continuació.
# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongodb-server-ip/hostname
Desa els canvis i reinicia el servei mongod. També heu de permetre al tallafoc les adreces IP remotes de confiança si heu habilitat el vostre tallafoc.
sudo ufw allow from trusted-server-ip to any port 27017
Per accedir a l’intèrpret d’ordres de MongoDB, executeu l’ordre mongosh al terminal tal com es mostra.
$ mongosh
Using MongoDB: 5.0.2
Using Mongosh: 1.0.5
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
..........
>
Per llistar les bases de dades existents executeu:
> show dbs
admin 135 kB
config 111 kB
local 73.7 kB
Per crear un usuari i afegir un rol a MongoDB
Vegem com podem crear un usuari a MongoDB i donar-li rols d’administrador i permís per a totes les bases de dades:
Crea un usuari admin:
use admin
db.createUser(
{
user: 'admin',
pwd: 'password',
roles: [ { role: 'root', db: 'admin' } ]
}
);
exit;
Entrem amb l’usuari admin que acabem de crear:
$ mongosh -u admin -p
Creem un altre usuari:
> db.createUser({
user: "rusben",
pwd: "password",
roles: [{role: "userAdminAnyDatabase" , db: "admin"}]
});
{ ok: 1 }
Per permetre a un usuari tenir permís per a una base de dades específica.
db.createUser({
user: "john",
pwd: "123456789",
roles: [{role: "userAdmin" , db: "employees"}]
});
mongoimport --db activitat1 --collection people --authenticationDatabase admin --username admin --password password --drop --file /vagrant/persons.json
Per crear una nova base de dades a MongoDB, utilitzem l’ordre use. MongoDB no té l’ordre de creació. Com a exemple, creeu una nova base de dades anomenada prova.
> use employees
switched to db employees
Heu d’afegir informació a la base de dades perquè aparegui a la llista quan enumereu les bases de dades.
db.Employees.insertOne({name: "hale" , age: 20 , department: "IT"})
{
acknowledged: true,
insertedId: ObjectId("61252c7492f10ccae358d787")
}
Tingueu en compte que Collection.insert() està obsolet i hauríeu d’utilitzar insertOne, insertMany o bulkWrite.
Ara, quan mostreu les bases de dades, també hauríeu d’aparèixer la vostra base de dades nova.
> show dbs
admin 0.000GB
config 0.000GB
employees 0.000GB
local 0.000GB
Un cop hàgiu instal·lat MongoDB, és important assegurar-vos que el seu rendiment estigui en configuracions òptimes. A mesura que la informació augmenta, la nostra instal·lació de MongoDB hauria de poder gestionar-la i processar-la com s’esperava. L’escala es pot produir tant horitzontalment com verticalment. L’escalat horitzontal significa l’addició de recursos del servidor com ara RAM i CPU, mentre que l’escalat vertical és la introducció de més servidors a la nostra instal·lació.
Un escalat vertical, que és molt crucial en el rendiment global de MongoDB, està influenciat per certs factors, com ara: ús de memòria, nombre de connexions concurrents i WiredTiger Cache, entre d’altres. La memòria és un factor important que influeix molt en el rendiment de MongoDB. MongoDB utilitza WiredTiger com a motor d’emmagatzematge predeterminat i, per tant, conserva el 50% de (la memòria disponible -1) per a WiredTiger.
Per exemple, un servidor amb 8 GB de RAM tindrà un conservador de memòria de 0,5 * (8-1) per a WiredTiger. Per comprovar les estadístiques d’ús de la memòria cau i determinar si cal fer canvis, executeu l’ordre següent:
> db.serverStatus().wiredTiger.cache
{
'application threads page read from disk to cache count': 6,
'application threads page read from disk to cache time (usecs)': 46,
'application threads page write from cache to disk count': 184,
'application threads page write from cache to disk time (usecs)': 10501,
'bytes allocated for updates': 65768,
'bytes belonging to page images in the cache': 30285,
'bytes belonging to the history store table in the cache': 571,
'bytes currently in the cache': 104652,
'bytes dirty in the cache cumulative': 2813442,
'bytes not belonging to page images in the cache': 74366,
'bytes read into cache': 28042,
'bytes written from cache': 1283385,
'cache overflow score': 0,
'checkpoint blocked page eviction': 0,
'checkpoint of history store file blocked non-history store page eviction': 0,
'eviction calls to get a page': 2,
'eviction calls to get a page found queue empty': 2,
'eviction calls to get a page found queue empty after locking': 0,
'eviction currently operating in aggressive mode': 0,
'eviction empty score': 0,
'eviction passes of a file': 0,
'eviction server candidate queue empty when topping up': 0,
'eviction server candidate queue not empty when topping up': 0,
'eviction server evicting pages': 0,
'eviction server slept, because we did not make progress with eviction': 0,
'eviction server unable to reach eviction goal': 0,
'eviction server waiting for a leaf page': 0,
'eviction state': 64,
'eviction walk target pages histogram - 0-9': 0,
'eviction walk target pages histogram - 10-31': 0,
'eviction walk target pages histogram - 128 and higher': 0,
'eviction walk target pages histogram - 32-63': 0,
'eviction walk target pages histogram - 64-128': 0,
'eviction walk target pages reduced due to history store cache pressure': 0,
'eviction walk target strategy both clean and dirty pages': 0,
'eviction walk target strategy only clean pages': 0,
'eviction walk target strategy only dirty pages': 0,
'eviction walks abandoned': 0,
..............
Dels resultats anteriors, són de gran importància:
wiredTiger.cache.maximum bytes configuratwiredTiger.cache.bytes actualment a la memòria cauwiredTiger.cache.tracked bytes bruts a la memòria cauwiredTiger.cache.pages llegit a la memòria cauwiredTiger.cache.pages escrites des de la memòria cauLes mides actuals de l’anterior ens haurien de permetre prendre una decisió sobre si volem augmentar la mida del WiredTiger als nostres servidors. Una altra cosa igualment important és l’ús de bitllets de lectura i escriptura de concurrència de WiredTiger, que es pot comprovar de la següent manera:
> db.serverStatus().wiredTiger.concurrentTransactions
{
write: { out: 0, available: 128, totalTickets: 128 },
read: { out: 1, available: 127, totalTickets: 128 }
}
Si observeu que els números augmenten i tendeixen cap a aquest nombre disponible de nuclis, és possible que els vostres servidors s’apropin a la saturació de la CPU.
people
mongoimport --db activitat1 --collection people --authenticationDatabase admin --username admin --drop --file /vagrant/persons.json
./mongo localhost/activitat1
db.people.find()
db.people.find().pretty()
db.people.find({age : 34}).pretty()
db.people.find({age : 34, isActive : true}).pretty()
db.people.find( {age : 34, isActive : true}, {name : 1, age : 1})
db.people.find( {age : 34, isActive : true}, {name : 1, age : 1, _id : 0})
db.people.findOne( {age : 34, isActive : true}, {name : 1, age : 1, _id : 0})
db.people.find( {age : {$gt : 30}}, {name : 1, _id : 0})
db.people.find({age : { $gte : 30}},{name : 1, age : 1, _id : 0})
db.people.find({age : { $lt : 30}},{name : 1, age : 1, _id : 0})
db.people.find({age : { $ne : 30}},{name : 1, age : 1, _id : 0})
db.people.find({age : {$in : [25,30,35]}},{name : 1, age : 1, _id : 0})
db.people.find({gender : "female", age : {$gt : 20}})
db.people.find({$or : [{gender : "female"}, {age :{$gt : 20}}]},{})
db.people.find({$and : [{gender : "female"}, {age :{$gt : 20}}]},{})
db.people.find({$or: [{age : {$gt:30}}, {gender : "female"}]}, {})
db.people.find({$nor : [{age : {$gt : 30}}, {isActivate : true}]},{ name : 1, age:1,isActive:1})
db.people.find({tags : "laborum"},{name : 1, _id : 0})
db.people.find({$and : [{tags : "laborum"}, {tags : "sunt"}]}, {name : 1})
db.people.find({tags:{$all:["laborum","sunt"]}},{name:1,age:1,tags:1})
db.people.find({tags:{$in:["laborum","sunt","nisi"]}},{name:1,age:1,tags:1})
db.people.find({tags:{$nin:["laborum","sunt","nisi"]}},{name:1,age:1,tags:1})
db.people.find({tags:{$size:3}},{name:1,tags:1})
db.people.find({$or:[{tags:{$in:["laborum","sunt","nisi"]}}]},{name:1})
db.people.find({tags:{$in:["laborum","sunt"]}},{name:{$slice:3}})
db.people.find({tags:{$in:["laborum","sunt"]}},{name:{$slice:3} })
db.people.find({"hasActed": {$exists: true}, "hasDirected": {$exists: false}})
db.people.find({"hasActed": {$exists: false}, "hasDirected": {$exists: true}})
db.people.find({"hasActed": {$exists: true}, "hasDirected": {$exists: true}})
db.people.find({"hasActed": {$exists: false}, "hasDirected": {$exists: false}})
db.bios.find({"awards.year": 2001})
db.bios.find({"awards.award": "Turing Award"})
db.bios.find({"awards.award": /^National Medal of/i})
db.bios.find({"awards.award": {$regex : "National Medal of *"}},{})
db.bios.find({"birthYear": {"$exists": true}, "deathYear": {"$exists": false}})
db.bios.find({"$and": [{"birthYear": {"$exists": true}},{"deathYear": {"$exists": false}}]})
db.bios.find({"contribs": "OOP"})
db.bios.find({"contribs": {"$in": ["Java", "Ruby", "Python"]}})
db.bios.find({$or : [ {contribs: "Python"},{contribs : "Ruby"},{ contribs : "Java"}]},{})
db.bios.find({"contribs": {"$all": ["OOP", "Simula"]}})
db.bios.find({"$and": [{"contribs": "OOP"}, {"contribs": "Simula"}]})
db.bios.find({"$or": [{"awards": {"$exists": false}}, {"awards": {"$size": 0}}]})
db.bios.find({"awards": {"$size": 1}})
db.bios.find({"awards.2": {"$exists": true}})
db.bios.find({awards : {$exists : true}, $where : "this.awards.length >= 3"})
db.bios.find({$where:"if(this.awards && this.awards.length>2){return this;}"})
db.bios.find({"$or": [{"awards": {"$size": 2}}, {"awards": {"$size": 3}}, {"awards": {"$size": 4}}]})
db.bios.find({"$and": [{"awards.1": {"$exists": true}}, {"awards.4": {"$exists": false}}]})
db.bios.find({"awards.1": {"$exists": true}, "awards.4": {"$exists": false}})
db.bios.find({awards : {$exists : true}, $where : "this.awards.length >=2 this.awards.length <=4"},{})
db.bios.find({$where:"if(this.awards && this.awards.length>1 && this.awards.length<5){return this;}"})
db.books.find({$and : [{"price.currency" : "USD"}, {"price.msrp" : {$gt : 100}}]},{})
db.books.find({"author": "Martin Fowler"})
db.books.find({"tags": {"$all": ["programming", "agile", "java"]}})
db.books.find({"author": {"$all": ["Martin Fowler", "Kent Beck"]}})
db.books.find({"author": {"$size": 3}})
db.books.find({author : {$exists:true}, $where : "this.author.length == 3"}, {}).pretty()
db.books.find({"author": {"$not": {"$size": 1}}})
db.books.find({"author.1": {"$exists": true}})
db.books.find({author : {$exists:true}, $where : "this.author.length > 1"}, {})
db.products.find().pretty()
2. Executa la següent operació, captura el seu resultat i interpreta la operació realitzada prèviament
db.products.save({ _id: 890, nombre: “Portátil Lenovo”, cantidad: 7, precio: 800 })
db.products.find().pretty()
3. Executa la següent operació, captura el seu resultat i interpreta la operació realitzada prèviament
db.products.remove({_id:890}) db.products.find().pretty()
4. Executa la següent operació, captura el seu resultat i interpreta la operació realitzada prèviament
db.products.insert([ { nombre: “HDD Seagate”, cantidad: 45, precio: 79.99, tipo: “HDD” }, { nombre: “HDD Maxtor”, cantidad: 20, precio: 65.50, tipo: “HDD” } ])
db.products.find().pretty()
5. Actualitza el número d'unitats del HDD Maxtor a 30
db.products.update({nombre:”HDD Maxtor”},{cantidad:30}) db.products.find().pretty()
6. Substitueix el producte en questió pel HDD Maxtor, ignorant el que hi haguès abans.
db.products.update({ _id: ObjectId(“51e64cd2403754f2073712da”) }, { nombre: “HDD Maxtor”, cantidad: 30, precio: 65.5, tipo: “HDD” })
db.products.find().pretty()
7. Canvia nomès els valors cantidad i precio
db.products.update({ _id: ObjectId(“51e64cd2403754f2073712da”) }, { $set: { cantidad: 35, precio: 60 } })
db.products.find().pretty()
8. Deixa a 0 les existències de discs durs
db.products.update({tipo:”HDD”},{$set:{cantidad:0}}) db.products.find().pretty()
9. Canvia la el valor de la clau quantitat a 10 de tots els objectes que el valor de ‘tipo’ sigui
‘HDD’
db.products.update({tipo:”HDD”},{$set:{cantidad:10}},{multi:true}) db.products.find().pretty()
10. Actualitza els objectes que tinguin tipus ‘RAM’ amb els valors establerts, si no troba cap
coincidencia, crea un de nou.
db.products.update({ tipo: “RAM” }, { nombre: “Kingston 2Gb”, cantidad: 50, precio: 26.50, tipo: “RAM” }, { upsert: true })
db.products.find().pretty()
11. Actualitza els objectes que tinguin tipus ‘RAM’ amb els valors establerts, si no troba cap
coincidencia, crea un de nou.
db.products.update({ tipo: “RAM” }, { nombre: “Kingston 4Gb”, cantidad: 50, precio: 26.50, tipo: “RAM” }, { upsert: true }) db.products.find().pretty()
## Aggregation
1. Mostra per a cada gènere el nombre d'estudiants segons el model de resultat següent:
{ “gender” : “H”, “students” : 2895 } { “gender” : “M”, “students” : 348 }
db.students.aggregate([ { “$group”: { “_id”: “$gender”, “num”: {“$sum”: 1} } }, { “$project”: { “_id”: false, “gender”: “$_id”, “students”: “$num” } }, { “$sort”: { “students”: -1} } ])
2. Mostra per a cada gènere el nombre d'estudiants segons el model de resultat següent:
{ “gender” : “H”, “description” : “Hombre”, “students” : 2895 } { “gender” : “M”, “description” : “Mujer”, “students” : 348 }
db.students.aggregate([ { “$group”: { “_id”: “$gender”, “num”: {“$sum”: 1} } }, { “$project”: { “_id”: false, “gender”: “$_id”, “description”: {“$cond”: [ { $eq: [ “$_id”, “H” ]} , “Hombre”, “Mujer”]}, “students”: “$num” } }, { “$sort”: { “students”: -1} } ])
3. Mostra per a cada any el nombre d'estudiants segons el model de resultat següent:
{ “year” : 1990, “students” : 98 } { “year” : 1989, “students” : 69 } { “year” : 1988, “students” : 87 }
db.students.aggregate([ { “$group”: { “_id”: “$birthYear”, “num”: {“$sum”: 1} } }, { “$project”: { “_id”: false, “year”: “$_id”, “students”: “$num” } }, { “$sort”: { “year”: -1} } ])
4. Mostra per a cada any i gènere el nombre d'estudiants segons el model de resultat següent:
{ “year” : 1992, “gender” : “M”, “students” : 13 } { “year” : 1992, “gender” : “H”, “students” : 87 } { “year” : 1991, “gender” : “M”, “students” : 9 }
db.students.aggregate([ { “$group”: { “_id”: { “year”: “$birthYear”, “gender”: “$gender” }, “num”: {“$sum”: 1} } }, { “$project”: { “_id”: false, “year”: “$_id.year”, “gender”: “$_id.gender”, “students”: “$num” } }, { “$sort”: { “year”: -1, “gender”: -1} } ])
5. Mostra per a cada any les dades obtingudes segons el model de resultat següent:
{
“year” : 1993,
“total” : 97,
“males” : 81,
“females” : 16,
“malesper” : 83.50515463917526,
“femalesper” : 16.49484536082474
}
{
“year” : 1992,
“total” : 100,
“males” : 87,
“females” : 13,
“malesper” : 87,
“femalesper” : 13
}
db.students.aggregate([ { “$group”: { “_id”: “$birthYear”, “ntotal”: {“$sum”: 1}, “nmales”: {“$sum”: {“$cond”: [ {“$eq”: [“$gender”,”H”]}, 1, 0]}}, “nfemales”: {“$sum”: {“$cond”: [ {“$eq”: [“$gender”,”M”]}, 1, 0]}}, } }, { “$project”: { “_id”: false, “year”: “$_id”, “total”: “$ntotal”, “males”: “$nmales”, “females”: “$nfemales”, “malesper”: {“$multiply”: [{“$divide”: [“$nmales”, “$ntotal”]} , 100]}, “femalesper”: {“$multiply”: [{“$divide”: [“$nfemales”, “$ntotal”]}, 100]} } }, { “$sort”: { “year”: -1} } ]).pretty()
6. Mostra per a cada autor el nombre de llibres escrits segons el model de resultat següent:
{ “author” : “Andrew Hunt”, “books” : 6 } … { “author” : “Christian Heilmann”, “books” : 2 } { “author” : “Bill Dudney”, “books” : 2 }
db.books.aggregate([ {“$unwind”: “$author”},
{“$group”: {“_id”: “$author”, “nbooks”: {“$sum”: 1}}},
{“$project”: {“_id”: false, “author”: “$_id”, “books”: “$nbooks”}},
{“$sort”: {“books”: -1}} ]) ```
db.movies.aggregate([ {“$unwind”: “$actors”}, {“$group”: {“_id”: “$actors.name”, “nmovies”: {“$sum”: 1}, “lmovies”: {“$push”: “$name”}}},
{“$project”: {“_id”: 0, “actor”: “$_id”, “movies”: “$nmovies”, “catalog” : “$lmovies”}},
{“$sort”: {“movies”: -1}} ]) ```
db.movies.aggregate([
{“$sort”: {“year”: -1}},
{“$unwind”: “$actors”},
{“$group”: {
“_id”: “$actors.name”,
“nmovies”: {“$sum”: 1},
“lyear”: {“$max”: “$year”},
“fyear”: {“$min”: “$year”},
“tduration”: {“$sum”: “$runtime”},
“lmovies”: {“$push”: {“$concat”: [“$name”, “ (“, {“$substr”: [“$year”, 0, -1]}, “)”]}}
}
},
{
“$sort”: { “nmovies”: -1}
}
])
9. Mostra per a cada director les dades obtingudes segons el model de resultat següent:
{ “director” : “Billy Wilder”, “movies” : 4, “catalog” : [ “Lost Weekend, The”, “Stalag 17”, “Apartment, The”, “Fortune Cookie, The” ] } { “director” : “John Huston”, “movies” : 4, “catalog” : [ “Key Largo”, “Treasure of the Sierra Madre, The”, “African Queen, The”, “Prizzi’s Honor” ] } { “director” : “Fred Zinnemann”, “movies” : 4, “catalog” : [ “High Noon”, “From Here to Eternity”, “Man for All Seasons, A”, “Julia” ] }
db.movies.aggregate([ {“$unwind”: “$directors”}, {“$group”: {“_id”: “$directors.name”, “nmovies”: {“$sum”: 1}, “lmovies”: {“$push”: “$name”}}},
{“$project”: {“_id”: 0, “director”: “$_id”, “movies”: “$nmovies”, “catalog” : “$lmovies”}},
{“$sort”: {“movies”: -1}} ]) ```