4. Consultese en Mongo
4.1. find()
La comanda find ens permet recuperar els documents d'una col·lecció que coincideixen amb un criteri especificat com a document JSON. La seva sintaxi bàsica és la següent:
| JavaScript | |
|---|---|
{edad:20} no és el mateix que {edad:"20"}.
D'altra banda, també hem de considerar que el document buit {} coincideix amb tots els documents, de manera que la consulta
db.collection.find({}) retornaria tots els objectes de la col·lecció.
4.1.1. Quines claus recuperar?
La comanda find retorna els documents complets que coincideixen amb els criteris de selecció. Si no volem obtenir totes les claus, podem especificar quines claus volem consultar, incloent-les en un segon paràmetre:
| JavaScript | |
|---|---|
Com podem veure, aquest segon paràmetre també s'expressa en format JSON (de nou) i està format per dues claus (key_1 i key_2), ambdues amb un valor d'1. Aquest valor numèric també s'interpreta com a true. És a dir, especifiquem aquí quins són els camps que volem mostrar. En cas que vulguem mostrar tots els camps i amagar-ne alguns, utilitzaríem la mateixa sintaxi, però ara fent servir un 0 per aquells camps que volem amagar.
4.1.2. Operacions de comparació
MongoDB ens permet realitzar comparacions amb dades numèriques, sempre utilitzant el format de document JSON
db.collection.find({key: {$operator:value} });
Els operadors de comparació que podem utilitzar a MongoDB són:
$lt→ Menor que$lte→ Menor o igual que$gt→ Major que$gte→ Major o igual que
4.1.3. Operació OR
Si volem realitzar un filtre o consulta on es compleixin diverses condicions (una operació AND), només haurem de separar-les per comes en el mateix document JSON que utilitzem com a criteri. D'altra banda, si el que volem és dur a terme una operació OR, hem d'utilitzar un operador especial.
4.1.4. Operadors $IN i $NIN
Un cas especial d'OR és quan volem comprovar si un camp es troba dins d'un conjunt específic de valors. És a dir, si és un valor o un altre. Per això utilitzem l'operador $in, de la següent manera:
| JavaScript | |
|---|---|
De manera similar, existeix l'operador $nin (Not In), que obté els documents on el valor especificat no es troba a la llista. Hem de tenir en compte que en aquest últim cas també es mostraran aquells documents que tinguin un valor nul per a la clau.
4.1.5. Operador $OR
Quan volem realitzar l'operació OR en diferents camps del document, utilitzarem l'operador $OR, al qual passem un vector de possibles condicions, de la següent manera:
| JavaScript | |
|---|---|
Attention
Les condicions del array son condicions en json
4.1.6. Operador $NOT
L'operador $NOT és un operador metacondicional, és a dir, sempre s'aplica a un altre criteri, invertint el seu valor de certesa. La seva sintaxi seria:
| JavaScript | |
|---|---|
4.1.7. Operador $EXISTS
Recordem que en MongoDB, els documents no tenen una estructura o esquema comú, per la qual cosa és possible que hi hagi claus definides només en alguns d'ells. L'operador $exists s'utilitza per comprovar l'existència o no d'una determinada clau.
La sintaxi a utilitzar seria:
| JavaScript | |
|---|---|
Amb això obtenim els documents per als quals la clau existeix o no, depenent de si hem indicat true o false a la consulta.
4.2. Resultats de les consultes i tipus de dades
Els tipus de dades a MongoDB poden tenir alguns comportaments especials. Veurem alguns casos per saber què fer en determinades situacions.
4.2.1. valors nulls
El valor null coincideix amb les següents situacions:
- Quan el valor de la clau és null, o
- Quan la clau no existeix en el document (en aquest cas, normalment es diu que el camp no està informat)
4.2.2. Expressions regulars i cadenes de caràcters
Quan apliquem un filtre de document per un camp de text, pot ser que no coneguem exactament el valor del camp pel qual volem filtrar. Les expressions regulars ofereixen un mecanisme molt potent per a la coincidència de cadenes.
MongoDB ens permet utilitzar aquestes expressions de diverses maneres, ja sigui utilitzant expressions regulars de Javascript o utilitzant l'operador $regex, que utilitza Expressions Regulars Compatibles amb Perl (PCRE). Les expressions regulars de Javascript s'expressen utilitzant la següent sintaxi:
| JavaScript | |
|---|---|
Com podem veure, utilitzem un patró similar a una cadena de text, però utilitzant la barra inclinada / com a delimitador en lloc de les cometes ('). Per la seva banda, si utilitzem l'operador $regex, podem utilitzar la següent sintaxi:
| JavaScript | |
|---|---|
Podem trobar diverses opcions per a expressions regulars:
i→ Les coincidències no distingeixen entre majúscules i minúscules:{name:/john/i}{name: { $regex: 'john',$options: 'i'}}
m→ Permet incloure caràcters com^o$, per coincidir al principi o al final, en cadenes amb múltiples línies.{name:/^John/m}{name: { $regex: 'John', $options: 'm'}}
xIgnora els espais en blanc en el patró$regex, sempre que no estiguin escapats o inclosos en una classe de caràcters.{name: { $regex: ' J oh n',$options: 'x'}}
sPermet que el caràcter punt (.) representi qualsevol caràcter, incloent el caràcter de nova línia.{name:/ju.n/s}{name: { $regex: 'thu.n',$options: 's'}}
Podeu trobar més informació sobre expressions regulars i casos particulars en què es recomana utilitzar un tipus d'expressió o una altra en la documentació oficial de MongoDB sobre $regex aquí.
4.3. Consideracions sobre el tipus de dades de les consultes
4.3.1. Consultes amb arrays
Per cercar elements coincidents dins d'un array, procedim amb la mateixa sintaxi com si fos qualsevol altra clau, utilitzant el document de consulta {key:value}, sent la clau un array, i el valor, ja sigui un n valor que ha de contenir l'array, o un altre vector ordenat que volem que coincideixi exactament.
Per exemple:
db.collection.find({ my_vector : value })→ Coincideix amb tots els documents en els quals el vectormy_vectorapareix, en la posició que sigui, el valor indicat.db.users.find({roles:"admin"})mostra els usuaris que en l'arrayrolestenen el rol admin (o altres).
db.collection.find({ my_vector : [value] })→ Coincideix amb tots els documents en els quals el vectormy_vectorapareix només el valor indicat.db.users.find({roles:["admin"]})mostra els usuaris que tenen exactament el rol admin.
A més, també podem utilitzar expressions regulars o la resta d'operadors que hem vist com a condicions.
D'altra banda, també podem referir-nos a un element específic del vector pel seu índex, utilitzant la notació de punts i entre cometes:
db.collection.find({"my_vector.position" :[value]})db.users.find({"roles.2":["admin"]})mostra l'usuari que té com a tercer rol admin
4.3.2. L'operador $all
Amb $all podem especificar més d'un element coincident dins de l'array:
db.collection.find({ my_vector : {$all:[value1, value2,...]}})db.users.find({roles:{$all:["mod","admin"]}})mostra els usuaris que tenen els rols mod i admin (i possiblement altres).
4.3.3. L'operador $size
Utilitzant $size podem incloure condicions sobre la longitud dels vectors:
db.collection.find({ my_vector : {$size:size} })
4.3.4. L'operador $slice
L'operador slice ens permet obtenir un subconjunt dels elements del vector, amb la següent sintaxi:
key: {$slice: x}:- si x>0 obté els primers x elements
- si x<0, obté els últims x elements
key: {$slice: [ x , y ] }Obtén y elements des de l'element a la posició x del document embegut
Per consultar documents embeguts, simplement especifiqueu el camí complet de la clau, tancat entre cometes i separat per punts:
db.collection.find({"path.to.key":value_or_condition})
4.4. Cursors
Quan realitzem una consulta, MongoDB retorna els resultats utilitzant cursos, que són punters als resultats de la consulta, com connectors a la unitat 2. Els clients que utilitzen Mongo iteren sobre aquests cursos per recuperar els resultats, i ofereixen un conjunt de funcionalitats, com limitar els resultats, etc.
Quan realitzem una consulta en una base de dades amb molts resultats, el client (mongosh) retorna només 20 resultats i el missatge Type "it" for more, per continuar iterant el cursor.
4.4.1. Limit, Skip i Sort
MongoDB ens permet fer certes limitacions en els resultats. Entre elles, podem destacar:
limit→ Per limitar el nombre de resultatsskip→ Salta un nombre específic de resultats.sort→ Ordena els resultats. Necessites un objecte JSON amb les claus per ordenar, i un valor de 1 per ordenar ascendentment o -1 per ordenar descendentment.
4.5. Introducció al Marc d'Agrupació
Les consultes d'agrupació que realitzàvem amb operadors com GROUP BY, SUM o COUNT en SQL es poden realitzar amb el Marc d'Agrupació de MongoDB. Les consultes d'agrupació tenen la següent sintaxi:
| JavaScript | |
|---|---|
El pipeline o tuberia té un concepte similar a les tiberies d'Unix: els resultats d'una ordre es passen com a entrada a una altra, per obtenir resultats conjuntament.
Les operacions que podem realitzar dins d'aquestes consultes d'agrupació són:
$project→ Per realitzar una projecció sobre un conjunt de dades d'entrada, afegint, eliminant o recalculant camps perquè la sortida sigui diferent.$match→ Filtra l'entrada per reduir el nombre de documents, deixant només aquells que compleixen certes condicions.$limit→ Restringeix el nombre de resultats.$skip→ Salta un cert nombre de registres.$unwind→ Converteix un array per retornar-lo separat en documents.$group→ Agrupa documents segons una certa condició.$sort→ Ordena un conjunt de documents, segons el camp especificat.$geoNear→ S'utilitza com a dades geoespacials, retornant els documents ordenats per proximitat segons un punt geoespacial.
Per realitzar càlculs sobre les dades produïdes per les canonades, utilitzarem expressions. Les expressions són funcions que realitzen una certa operació sobre un grup de documents, vector o camp específic. Algunes d'aquestes expressions són $max, $min, $divide o $substr.
Podeu trobar molta més informació sobre agregacions a la documentació oficial de MongoDB.
4.6. Exercicis
Seguim treballant amb la col·lecció de pel·lícules. En aquest cas, utilitzarem el terminal mongosh (o robo3t si ho prefereixes), i realitzarem les següents consultes sobre aquesta col·lecció.
- Obteniu totes les produccions que es van estrenar el
2015o que són del tipussèrie. - Obteniu totes les pel·lícules que NO es van estrenar entre els anys
2000i2002. - Obteniu totes les pel·lícules per a les quals la clau "directors" no està definida.
- Obteniu el títol de totes les pel·lícules que comencen amb la cadena
star wars, independentment de majúscules o minúscules. - Obteniu el títol de totes les pel·lícules que contenen el gènere comèdia (
Comedy). - Mostreu el títol i els gèneres de les pel·lícules que contenen el gènere comèdia (
Comedy) o aventura (Adventure). - Obteniu el títol i els gèneres de les pel·lícules que tenen tres gèneres.
- Obteniu les pel·lícules amb una qualificació de
Rotten Tomatoessuperior a4. - Feu la mateixa consulta que abans, però limitant el nombre de documents a 10.
- Ara mostreu el títol i la qualificació d'aquelles pel·lícules amb una qualificació superior a 4, ordenades per qualificació (de més alta a més baixa) i limitant els resultats a 10.