Capitolo 2

Find e FindOne: Cercare i Documenti


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

Find e FindOne: Cercare i Documenti

Tutto su come cercare i documenti: Find, FindOne, condizioni di ricerca e Field selection per escludere alcuni attributi dalla visualizzazione.

Lezione su FindOne

L’operazione basica dei database è la ricerca. Per ricercare un singolo documento si usa la findOne. Questa può essere richiamata senza argomenti per ricevere un documento random della collection, in questo modo:

>db.users.findOne()

Vi chiederete a che serve, beh diciamo che può essere utile per dare un’occhiata alla struttura dei documenti nelle collection molto grandi.


La findOne può essere invocata anche con un argomento che viene usato per fare un match con i documenti, diciamo che funziona come il WHERE nelle query SQL, quindi è una condizione. Vediamo un esempio:

>db.users.findOne( { name:”Alberto” } )

in questo caso viene restituito il primo documento che soddisfa il criterio di ricerca, ovvero la chiave nome deve avere il valore Alberto.


Come secondo parametro facoltativo possiamo anche specificare quali attributi vogliamo che ci vengano restituiti, ad esempio:

> db.users.findOne( {name: “Alberto”}, { name:true })

in questo caso mostrerà solo il nome.

Anche se noi non l’abbiamo specificato ci verrà mostrato anche l’_id. Se non lo vogliamo dobbiamo precisarlo, in questo modo:

> db.users.findOne( {name: “Alberto”}, { name:true, _id:false })


Lezione su Find


Adesso vediamo la funzione find che nonostante abbia delle similitudini con la findOne ci mostra più risultati.


Prima di tutto predisponiamo una collection per tutte le nostre prove, ci serve una collection bella grande cosi da fare vari test. Scriviamo:


for ( var i=0; i<1000; i++ ) { names = ["esame","prova","quiz"]; for(var j=0;j<3;j++){ db.scores.insert( { student: i, type: names[j], score: Math.round( Math.random()*100 ) } ); } }


Se volete copiare il codice lo trovate sotto il video nella pagina della lezione sul sito mongodbitalia.it.


Spieghiamo cosa fa questo codice perchè non essendo indentato si ben capisce poco, essenzialmente popola una nuova collection con dei punteggi di varie prove o esami per 1000 studenti.

Più precisamente abbiamo un primo ciclo che viene eseguito 1000 volte, per tutti gli studenti, all’interno di questo abbiamo un secondo ciclo che viene eseguito solo 3 volte, l’indice di questo secondo ciclo viene utilizzato per scegliere il tipo di prova/esame. Quindi per ogni ciclo viene salvato il numero dello studente, che corrisponde all’indice del primo ciclo, il tipo di prova e un numero casuale che rappresenta il voto.

Proviamo a visualizzare la nostra collection:

> db.scores.find()


Dal momento che abbiamo molti documenti non può di certo restituirci tutto assieme, e figuriamoci che adesso ne abbiamo solo 3000; ma immaginate se ce ne fossero stati 10.000 o 100.000 e pure più elaborati dei nostri, avremmo avuto sicuramente un picco di carico. Per evitare questo problema ci viene limitata automaticamente la query.

Per scorrere e visualizzare i risultati successivi possiamo scrivere IT, in questo modo il cursore andrà avanti.

Però così facendo i risultati sono poco leggibili, per avere una visualizzazione più pulita meglio scrivere:

> db.scores.find().pretty()


Field Selection: selezione attributi da visualizzare


Come abbiamo visto per findOne, anche nella funzione find possiamo specificare delle condizioni:

> db.scores.find( { type:”prova” } )

oppure:

> db.scores.find( { student:19 } )


Volendo possiamo anche combinare più condizioni insieme concatenandole con la virgola:

>db.scores.find( { type:”prova”, student:19 } )

In questo caso la virgola funge da AND perchè il documento deve soddisfare entrambe le richieste nello stesso momento.


Possiamo anche specificare il secondo argomento che serve per dichiarare esplicitamente quali attributi deve restituirci la query

>db.scores.find( { type:”prova”, student:19 }, { score:true } )

Di default ci verrà restituito anche l’_id  in quanto attributo speciale, se non lo vogliamo dobbiamo specificarlo.