You are on page 1of 15

Còmic feliç

Arnau Añols Bordas

Maria Ganduxé Beltran, 1606755

Jan Pérez Costa, 1562911

Bruno-Joan Tejedo i Miniéri, 1533327


INTRODUCCIÓ

Es vol fer una base de dades que ens permeti emmagatzemar les publicacions de col·leccions de
llibres de diferents editorials que disposa una tenda de còmics.

Per fer-ho, serà necessari importar una base de dades que tenim en un fitxer Excel, utilitzant un
codi en el llenguatge Python (que ens permeti també eliminar-ne en contingut quan sigui
necessari) per tal de posteriorment fer consultes i emmagatzemar informació.

Aquesta base de dades haurà de ser consistent, robusta i fàcil d’adaptar quan surtin documents
nous o algun atribut o camp nou.
Aquesta importació haurà de fer-se seguint el model de la nostra base de dades no-relacional,
és a dir, a partir de les col·leccions que hem triat dissenyar, els seus atributs i les corresponents
referències per tal de facilitar les consultes que haguem de fer. Això ho farem seguint els patrons
de disseny de les bases de dades no-relacionals, i a més haurem de tenir en compte uns
requeriments que se’ns demana per tal que la informació quedi ben guardada i les referències
entre les col·leccions també estiguin correctament. Aquests requeriments són els següents:

 Una editorial és una empresa que s’identifica pel nom i disposem del responsable,
adreça i país i que crea col·leccions de publicacions. De fet, una mateixa col·lecció es pot
crear en més d’una editorial.
 De les col·leccions en sabem el nom, total d’exemplars, gènere o gèneres al que pertany
(per exemple: terror, fantasia, etc). A més, de l’idioma en el que s’ha redactat, l’any
d’inici, l’any de finalització (si es que ha finalitzat) i un atribut que indica si la col·lecció
ha acabat o no.
 Cada col·lecció esta formada per diferents publicacions (llibres) que s’identifiquen amb
l’ISBN. També cal guardar el títol, autor, número de pàgines, stock i preu a tenda. A cada
llibre hi apareixen diversos personatges dels que volem guardar el nom i tipus. A més,
aquests personatges poden aparèixer en més d’una publicació.
 Per últim, guardarem els artistes que han participat en la creació de les publicacions.
Dels artistes guardem el nom artístic, nom, cognoms, data de naixement i país. Aquests
artistes poden participar tant com a guionistes com a dibuixants.

2
REPARTIMENT DE LA FEINA

Per tal de realitzar un bon treball, ha sigut prioritari repartir-se bé el treball i que tothom
contribuís amb el que sabés. És per això que ens hem distribuït la feina de la següent manera:

 Arnau: ha realitzar el primer exercici, és a dir, plantejar com crearíem les col·leccions i
els patrons i relacions que seguiran.
 Bruno: ha realitzat el segon exercici, és a dir, crear l’script en Python que permet
importar l’Excel i tot seguint les relacions i atributs que havíem plantejat anteriorment.
 Maria: ha executat l’script de Python per importar les dades i ha realitzat les consultes
demanades en l’enunciat.
 Jan: ha realitzat l’informe del treball, explicant els tres exercicis: les tres col·leccions,
l’script en Python, cadascuna de les consultes i ha fet l’apartat b) del segon exercici.

Veiem que la distribució de la feina ha estat equitativa i els 4 estem satisfets la feina feta.

3
EXERCICI 1

Volem fer una base de dades per emmagatzemar les publicacions de diferents col·leccions de
llibres amb la seva respectiva informació. Aquesta consta, a part de la informació explícita de
cada element (com per exemple el nom, gènere, etc de la col·lecció), de l’editorial de cada
col·lecció i els personatges i artistes de cada obra.

Donat el disseny Entitat-Relació i les consultes a fer, hem dissenyat la següent base de dades amb
les següents col·leccions:

 Col·leccions
o Nom
o Gèneres (llista)
o Idioma
o Any_inici
o Any_final
o Acabada (booleà)
o Publicacions: (llista)
 ISBN_publicació
o Editorials: (llista de subdocuments)
 Nom
 Responsable
 Adreça:
 País
 Total_exemplars

En aquesta col·lecció hem decidit utilitzar el patró embedded i encapsular l’entitat


Editorial en Col·leccions com un subdocument. Ho hem realitzat d’aquesta manera ja
que al poder tenir una o més editorials per cada col·lecció, podíem aplicar el patró de
referència però això hagués causat utilitzar molts joins i baixada de rendiment al realitzar
les consultes. Al aplicar el patró embedded, és més fàcil i ràpid al consultar i com que
cada col·lecció haurà estat creada en poques editorials com a molt, no augmentarà gaire
la complexitat.
D’altra banda, per relacionar l’entitat Col·leccions amb la de publicacions, hem aplicat el
patró de referència ja que una col·lecció pot tenir moltes obres i si apliquéssim
embedded tindríem una col·lecció molt gran.

 Publicacions
o ISBN
o Títol
o Autor
o Npàgines
o Stock
o Preu
o Personatges:
 Nom
 Tipus

4
o Guionistes (llista)
o Dibuixants (llista)

En aquesta col·lecció hem utilitzat dos patrons, el primer ha sigut referència estesa per
relacionar publicacions amb el seu autor. Hem utilitzat aquest patró perquè utilitzar
embedded generaria massa duplicitat de dades, i hem utilitzat específicament referència
estesa incloent l’atribut tipus ja que en diverses consultes ens demanen informació de
les publicacions segons l’autor si és guionista o dibuixant, així que d’aquesta manera
evitem joins.
L’altre patró utilitzat ha sigut l’embedded, per relacionar Publicacions amb Personatges.
Ho hem fet d’aquesta manera ja que l’entitat personatges és molt senzilla i no tindria
sentit fer una col·lecció apart només per ella.
Pel que fa als personatges, no era necessària crear una col·lecció, ja que els personatges
podran aparèixer en més d’una publicació però serà en llibres de la mateixa col·lecció, i
per tant la busca no es farà pesada o complexa.

 Artistes
o Nom artístic
o Nom
o Cognoms
o Data naixement
o País

En resum, hem creat tres col·leccions utilitzant patrons de disseny com l’embedded i el patró
referència estesa, el qual ens permet no haver d’utilitzar joins en les dades i menys $lookup al
realitzar consultes.

A més, per tal de facilitar la nostra feina en el projecte, vam haver de canviar part del disseny al
realitzar l’exercici 2, on vam veure que ens era més fàcil (i més òptim per la nostra base de dades)
tenir dues llistes a la col·lecció publicacions (guionistes, dibuixants) que contindran el tipus
d’artista (en el mateix títol de l’atribut) amb una llista dels artistes amb el seu nom artístic, que
és únic per a cada artista i els diferencia. Abans de veure aquest canvis teníem un atribut
anomenat tipus per cada artista i un atribut a col·lecció publicacions que contingui el ID de
l’artista i el seu tipus.

D’aquesta manera, per cada publicació, tindrem organitzats els artistes per el seu tipus i un
artista podrà ser guionista i dibuixant en obres diferents o les dues coses en la mateixa obra. De
l’altra manera cada artista havia de ser o guionista o dibuixant, però no podia ser les dues coses.

Pel que fa a les col·leccions, es relacionen amb la llista de l’atribut publicacions, que conté el
ISBN de les publicacions de cada col·lecció.
Finalment, veiem com hem citat i complert tots els requisits inicials.

5
EXERCICI 2

El primer que farem en aquest exercici, com en qualsevol codi Python que volem utilitzar en
MongoDB, és triar el host i el port.

A partir d’allà, seleccionem la base de dades pel nostre treball i creem les tres col·leccions:
artistes, col·leccions i publicacions.
Un cop tenim creades les col·leccions, llegirem les dades que conté el nostre Excel amb els
atributs i utilitzant els patrons i la distribució que hem triat nosaltres per tal de guardar-les en 3
datasets. Guardarem també la informació que conté els noms dels atributs en 5 tuples que
contindran les claus.

Ara sí, ja podem omplir les tres col·leccions utilitzant les claus i els datasets que hem extret de
cadascuna de les llibres que conté el nostre Excel.
Finalment, abans d’arribar al final, haurem de realitzar un control per tal de comprovar que no
dupliquem elements en la nostra base de dades. Per fer-ho, farem un control per cadascuna de
les col·leccions. Aquest control el realitzarem amb un bucle com aquest:
if coll1.count_documents({}) == 0:
for d in colleccions:
print(d) # d: 1 tupla registro
coll1.insert_one(d)
Pel que fa a esborrar les dades, si l’usuari executa python main.py -f Dades.xlsx --delete_all --
bd BDNRProject. Al haver rebut com a paràmetres el -- delete_all, esborrarem la base de
dades. Això és possible gràcies al codi del final del nostre document, que utilitza la llibreria
argpase i té com a condició que si s’utilitza l’argument –delete_all, esborrarà tota la base de
dades.

6
EXERCICI 3

Per l’exercici 3, que consisteix en realitzar 10 consultes en el nostre data set per comprovar que
l’accés a les dades no és complicat i que la base de dades conté dades correctes i ben
organitzades i distribuïdes.

1. Primera consulta: Les 5 publicacions amb major preu. Mostrar només el títol i preu.

Simplement hem de fer una cerca a la col·lecció publicacions amb un filtre per preu i al
moment d’imprimir els resultats, marquem amb un 1 els que volem mostrar, ordenem els
preus amb ordre descendent i marquem un límit de 5.

Els resultats obtinguts són els següents:

Comparant-ho amb les solucions, veiem que tot coincideix!

titol preu
Dracula 125.5
Tragedias 85.4
Romances 72.4
Crimen y castigo 59.4
En el Este 43.5

7
2. Segona consulta: Valor màxim, mínim i mitjà del preus de les publicacions de
l’editorial Juniper Books.

Comencem fent un filtre per seleccionar només les col·leccions de l’editorial Juniper Books.
Com que necessitem accedir a un camp de la col·lecció publicacions, utilitzem $lookup per
comparar els camps ISBN de la col·lecció publicacions amb el camp publicacions de la col·lecció
colleccions. A continuació, despleguem l’array publicacions per separar-les una a una utilitzant
$unwind i després utilitzem group per crear i calcular els camps demanats amb els operadors
$max, $min i &avg. Per últim, triem només els camps que volem que surtin per pantalla.

Els resultats obtinguts són els següents:

Un altre cop veiem que coincideixen, tot i que en el nostre cas, hem donat més precisió als
decimals.

maxim minim avg


32.5 27.85 29.12

8
3. Tercera consulta: Artistes (nom artístic) que participen en més de 5 publicacions com
a dibuixant.

Utilitzem $unwind per crear un document per cada dibuixant de cadascuna de les publicacions
per tal de poder-los agrupar després per dibuixant i calcular-ne el total. Fem un filtre per triar
els que dibuixen en més de 5 publicacions i en projectem només els noms artístics.

Els resultats són els següents:

Veiem que tornen a coincidir amb els resultats desitjats.

nom_artistic
Artista1
Artista2

9
4. Quarta consulta: número de col·leccions per gènere i número total.

Dividim la cadena de gèneres en un array per poder descompondre’n els elements en


documents separats. Això ho hem hagut de fer per tal que no ens classifiqui els documents per
més d’un gènere (és a dir que no prengui com a un únic gènere, per exemple, la combinació:
fantasia i suspens). Posteriorment, els agrupem per gènere i comptem quants documents
tenen cadascun dels gèneres i projectem el camp total i el camp de gènere.

Els resultats obtinguts, aquest cop no coincideixen amb els esperats, sembla que falta un
document que contingui el gènere fantasia i un que contingui el gènere màgia (o un de sol que
contingui els dos gèneres).

genere num_coll
fantasia 4
belica 2
magia 2
suspense 1
clasicos 1

10
5. Cinquena consulta: per cada editorial, mostrar el recompte de col·l3ccions
finalitzades i no finalitzades.

Separem la col·lecció utilitzant el camp editorials per crear documents separats. A partir d’allà,
utilitzem group per crear dos nous camps que ens serviran, un per calcular el total de
col·leccions finalitzades i l'altre per calcular les que no ho estan. Aquest dos valors, es
calcularan per cadascun dels valors de $editorials.NomEditorial. Al final, projectarem només els
editorials i les dues sumes per cadascun dels editorials.

Els resultats obtinguts:

Tornen a coincidir amb els esperats.

editorial final nofinal


Juniper Books 2 0
Penguin 1 1
The Folio Society 1 0

11
6. Sisena consulta: mostrar les 2 col·leccions ja finalitzades amb més publicacions.
Mostrar editorial i nom col·lecció.

Primer filtre les que estan finalitzades i separem l’array d’editorials per tal que es creï un nou
document amb un sol editorial per document. Creem nous camps seleccionant els noms de
l’editorial i de la col·lecció i el total de publicacions, que ens servirà per ordenar els resultats de
manera descendent. Apliquem el límit de dues col·leccions i se’ns mostrar les dues amb més
publicacions.

Els resultats obtinguts:

Tornen a coincidir!

editorial coll
Juniper Books Harry Potter
Penguin Harry Potter

12
7. Sèptima consulta: mostrar el país d’origen de l’artista o artistes que han fet més
guions.
En aquesta consulta no hem aconseguit obtenir els resultats esperats. Potser ens ha faltat
realitzar un $unwind en el camp de guionistes per separar-los i tenir un document per cada
guionista de cada publicació. Posteriorment ajuntar-los per nom artístic dels guionistes per tal
d’agrupar tots els documents amb el mateix guionista. Després triem imprimir només el país i
com a límit posarem 1.

13
8. Vuitena consulta: mostrar les publicacions amb tots els personatges de tipus:
“heroe”.

Abans de fer aquesta consulta, hem hagut de realitzar un update, ja que ens hem donat
compte de que hi havia alguna dada de la nostra base de dades que estava mal escrita i, per
tant, alterava els resultats de la consulta. Aquest canvi l’hem fet amb el següent codi.

db.publicacions.updateOne(

{ "personatges.tipus": "heror" },

{ $set: { "personatges.$.tipus": "heroe" } }

Utilitzem find per trobar els que no tenen un tipus que posi heroi i no seleccionar-los. Per tant
ens quedarem amb els que sí ho són. Per últim decidim mostrar l’identificador de les
publicacions.

Els resultats obtinguts són:

Per tant, tornem a coincidir amb els esperats!

ISBN
4
20
22

14
9. Novena consulta: modificar el preu de les publicacions amb stock superior a 20
exemplars i incrementar-lo un 25%.

Fent servir la opció updateMany, primer hem fet un filtre per seleccionar només els que tenen
stock superior a 20.

A partir d’aquí, teníem dos opcions, o sumar un 25% del preu al que ja teníem, o multiplicar el
preu que ja tenim per 1.25 amb l’operador $mul. Nosaltres hem triat la segona opció.

10. Desena consulta: mostrar ISBN i títol de les publicacions conjuntament amb tota la
seva informació dels personatges.

Només hem de seleccionar les caselles a mostrar.

Els resultats obtinguts són cadascun dels documents de la col·lecció però mostrant només el
ISBN, el títol i tota la informació dels personatges.

15

You might also like