Capitolo 2

Operatori $EXISTS, $TYPE e $REGEX


Capitolo 2: CRUD


Presentazione CRUD e Operatori
Insert: Aggiungere Documenti
Find e FindOne: Cercare i Documenti
Operatori $GT e $LT: Maggiore di e Minore di
Operatori $EXISTS, $TYPE e $REGEX
Combinare le Query con $AND e $OR
La Ricerca e gli Array
Operatori $ALL, $IN e $NIN
La Ricerca e i Sotto-Documenti
Limit, Sort, Skip e Count
Update: i Primi Due Approcci
Update e gli Array
Update: Upsert e Multi-Update
Remove e Drop: Eliminare i Documenti

Operatori $EXISTS, $TYPE e $REGEX

Alcuni operatori utili sono sicuramente $exists, $type ed infine $regex per le espressioni regolari, impariamo ad usarli con qualche esempio.

Lezione su $exists e $type

Nell’altra lezione abbiamo visto $gt ed $lt e se avete capito come applicarli non avrete nessuna difficoltà neanche con quelli che vedremo oggi: $exists, $type e $regex.

Lanciamo:

>db.users.find()


Come possiamo vedere all’interno di questa collection abbiamo strutture differenti quindi vogliamo selezionare solo i documenti che hanno una città, per farlo ci serve l’operatore $exists che ci permette di verificare l’esistenza di un attributo all’interno dei documenti. Vediamo come usarlo:

> db.users.find( { city:{ $exists:true } } )

Come per $gt e $lt specifichiamo la chiave sul quale vogliamo applicare l’operatore, apriamo un sottodocumento e inseriamo quindi l’operatore come coppia chiave-valore.


Possiamo anche scrivere l’inverso, quindi tutti i documenti che non hanno una città:

> db.users.find( { city:{ $exists: false } } )


Con l’operatore $type invece possiamo chiedere se un attributo sia di un tipo specifico, questo lo userete di rado ma vediamo come funziona:

> db.users.find( { name:{ $type: 2 } } )


I tipi, dobbiamo scriverli come numero in base alle specifiche BSON, infatti nel BSON le stringhe hanno il valore 2, possiamo vedere la lista di tutti i tipi supportati sul sito bsonspec.org, sotto la voce specifiche.


Lezione su $regex

Ora passiamo al pezzo forte: la $regex, usata per le espressioni regolari. Diciamo che Mongo ci offre strumenti di query migliori di questo ma per adesso è il più potente che vedremo.

Per chi non conosce le espressioni regolari diciamo che permettono di effettuare controlli in base a regole o modelli sulle stringhe, cioè possiamo cercare tutte le stringhe che iniziano con una determinata lettera oppure che finiscono con un’altra e volendo possiamo creare regole complesse ed elaborate.


Non posso soffermarmi a parlare a lungo delle espressioni regolari perchè ci sarebbe veramente troppo da dire, e non sono neanche così esperto a dirla tutta. In questo corso vedremo come si usano su Mongo con qualche esempio che possa essere utile a tutti. Iniziamo:

> db.users.find( { name:{ $regex: “a” } } )


Con questo comando abbiamo chiesto di cercare tutti i nomi che contengono una a minuscola, attenzione non maiuscola ma solo minuscola.

Questo è un utilizzo banale delle espressioni regolari proviamo a sfruttarle meglio:


> db.users.find( { name:{ $regex: “e$” } } )


Attenzione il dollaro all’interno delle virgolette fa parte della simbologia delle espressioni regolari e indica la fine della stringa. Quindi in questo caso ci verranno restituiti tutti i documenti con nomi che finiscono con la lettera minuscola e.


$regex è sicuramente un operatore molto potente ma il suo utilizzo non è consigliato.

Attenzione, non voglio sminuire in nessun modo questa funzione ma le performance sono molto influenzate dalla complessità del pattern e dalla struttura dei dati, quindi se non da le certezze che servono in un sistema scalabile è preferibile non utilizzarlo.

Ovviamente Mongo ha tante risorse e ci offre ottime soluzioni per effettuare ricerche su testi in maniera molto performante, possiamo usare: gli indici appositi, detti Text Index, e l’operatore $text, purtroppo noi non vedremo nessuno dei due in quanto argomenti avanzati, mi dispiace...

Per il momento accontentiamoci di $regex che dovrebbe andar bene per il 90% dei normali database.


L’unica espressione regolare performante è questa:

> db.users.find( { name:{ $regex: “^A” } } )

il simbolo ^ nell’espressione regolare ci permette di ottenere tutti i documenti che iniziano con una determinata lettera. In realtà la query è considerata performante perchè viene convertita meccanicamente in un range, nel caso dell’esempio va da A a B con B esclusa.


Beh abbiamo visto un sacco di cose nuove: $exists per verificare se un attributo esiste o meno, $type (che non userete quasi mai) per verificare se un attributo è di un tipo specifico e poi $regex per le espressioni regolari o pattern matching, tante belle cose :) divertitevi!