Noțiuni de bază cu MongoDB - Partea 2

Sunteți gata să continuați să învățați despre MongoDB, una dintre cele mai bune tehnologii pentru dezvoltatorii web? În această a doua parte a seriei, trecem de la elementele de bază, până la interogări avansate - cu operatori condiționați - și MapReduce.


Pasul dincolo de elementele de bază

Anterior, am acoperit elementele de bază și cum să începem cu mongoDB, una dintre cele mai bune soluții de raportare a implementărilor NoSQL. Am analizat modul de instalare, crearea unei baze de date de bază și efectuarea operațiunilor de bază pe aceasta:

  • căutare
  • Actualizați
  • șterge

În plus, am început să ne uităm la modul de a începe să interacționăm cu mongoDB într-un mod mai puternic, prin utilizarea selectorilor. Selectorii ne dau posibilitatea de a avea control mult mai fin și să săpăm destul de adânc pentru a găsi datele pe care le dorim cu adevărat.

Acum este bine și bine să începeți, dar când doriți să scrieți o aplicație reală, trebuie să mergeți mult mai departe. Păi, asta e încă Noțiuni de bază dar în cele din urmă vreau să vă fac entuziasmați de posibilitățile de a lucra într-un mod orientat spre documente. Vreau să vă entuziasm să luați această tehnologie minunată și să o faceți și să o utilizați cât mai puternic posibil pentru a face aplicații fantastice.

Astăzi, vom extinde întrebările din ultima oară și vom învăța două aspecte-cheie ale mongoDB:

  • Întrebări avansate
  • MapReduce

Întrebări avansate

Anterior am analizat interogările de bază și am fost introduși selectorilor. Acum vom ajunge la întrebări mai avansate, construindu-ne pe lucrarea anterioară în două moduri-cheie:

  • Operatorii condiționați
  • Expresii obisnuite

Fiecare dintre acestea oferă succesiv mai mult control asupra cererilor pe care le putem scrie și, în consecință, informațiile pe care le putem extrage din bazele noastre de date mongoDB.

Operatorii condiționați

Operatorii subordonați sunt, așa cum sugerează și numele, operatori la interogări de colectare care rafinează condițiile în care interogarea trebuie să se potrivească la extragerea datelor din baza de date. Există o serie de ele, dar astăzi mă voi concentra pe 9 cele cheie. Acestea sunt:

  • $ lt - valoarea trebuie să fie mai mică decât condiționată
  • $ gt - valoarea trebuie să fie mai mare decât condiționată
  • $ lte - valoarea trebuie să fie mai mică sau egală cu cea condiționată
  • $ GTE - valoarea trebuie să fie mai mare sau egală cu cea condiționată
  • $ în - valoarea trebuie să fie într-un set de condiționalități
  • $ nin - valoarea nu trebuie să fie într-un set de condiționalități
  • $ nu - valoarea trebuie să fie egală cu o condiție

Să ne uităm la fiecare la rândul său. Deschideți terminalul și pregătiți-vă să utilizați baza de date originală din prima parte din această serie (pre-modificări). Pentru a face acest tutorial mai ușor, vom face o ușoară modificare a bazei de date. Vom da fiecare document din colecția noastră un atribut de vârstă. Pentru aceasta, executați următoarea interogare de modificare:

 db.nettuts.update ("_ id": ObjectId ("4ef224be0fec2806da6e9b27"), "$ set": "vârstă": 18); db.nettuts.update ("_ id": ObjectId ("4ef224bf0fec2806da6e9b28"), "$ set": "vârstă": 45); db.nettuts.update ("_ id": ObjectId ("4ef224bf0fec2806da6e9b29"), "$ set": "vârstă": 65); db.nettuts.update ("_ id": ObjectId ("4ef224bf0fec2806da6e9b2a"), "$ set": "vârstă": 43); db.nettuts.update ("_ id": ObjectId ("4ef224bf0fec2806da6e9b2b"), "$ set": "vârstă": 22); db.nettuts.update ("_ id": ObjectId ("4ef224bf0fec2806da6e9b2c"), "$ set": "vârstă": 45); db.nettuts.update ("_ id": ObjectId ("4ef224bf0fec2806da6e9b2d"), "$ set": "vârstă": 33);

Toate fiind bune, puteți rula un "găsi tot" și veți avea următoarea ieșire:

 db.nettuts.find (); "_id": ObjectId ("4ef224be0fec2806da6e9b27"), "vârsta": 18, "dob": "21/04/1978", "prima": "mathew", "gender": "m", hair_colour: "maro", "ultima": "setter", "naționalitate": "australian", "ocupație": "dezvoltator" "_id": ObjectId ("4ef224bf0fec2806da6e9b28"); "26/03/1940", "prima": "james", "gender": "m", "hair_colour": "maro", "last": "caan" : "actor" "_id": ObjectId ("4ef224bf0fec2806da6e9b29"), "vârstă": 65, "dob": "03/06/1925" "," hair_colour ":" maro "," last ":" schwarzenegger "," naționalitate ":" american "," ocupație ":" actor ":" age ": ObjectId (" 4ef224bf0fec2806da6e9b2a ") 43, "dob": "21/04/1978", "prima": "tony", "gender": "m", "hair_colour": "maro", "last": "curtis", "nationality": "american", "ocupație": "dezvoltator" "_id": ObjectId ("4ef224bf0fec2806da6e9b2b"), "age": 22, "dob" , "sex": "f", "păr _colour ":" maro "," ultim ":" curtis "," naționalitate ":" american "," occupation ":" actor " dob ":" 14/03/1933 "," prima ":" michael "," gen ":" m "," hair_colour ":" maro " , "ocupație": "actor" "_id": ObjectId ("4ef224bf0fec2806da6e9b2d"), "vârstă": 33, "dob": "09/12/1934" : "f", "hair_colour": "alb", "ultima": "dench", "naționalitate": "engleză", "ocupație": "actriță"

$ Lt / $ lte

Acum, să găsim toți actorii care au mai puțin de 40 de ani. Pentru a face acest lucru, executați următoarea interogare:

 db.nettuts.find ("vârsta": "$ lt": 40);

După ce executați această interogare, veți vedea următoarea ieșire:

 "_id": ObjectId ("4ef224be0fec2806da6e9b27"), "vârsta": 18, "dob": "21/04/1978", "prima": "mathew", "gender": "m", hair_colour: "maro", "ultima": "setter", "naționalitate": "australian", "ocupație": "dezvoltator" "_id": ObjectId ("4ef224bf0fec2806da6e9b2b"); "22:15", "prima": "jamie lee", "gen": "f", "hair_colour": "maro" : "actor" "_id": ObjectId ("4ef224bf0fec2806da6e9b2d"), "vârstă": 33, "dob": "09/12/1934" f "," hair_colour ":" alb "," ultima ":" dench "," naționalitate ":" engleză "," ocupație ":" actriță "

Ce-i cu cei care sunt mai puțin de 40 inclusiv? Rulați următoarea interogare pentru a returna rezultatul:

 db.nettuts.find ("vârstă": "$ lte": 40);

Aceasta returnează următoarea listă:

 "_id": ObjectId ("4ef224be0fec2806da6e9b27"), "vârsta": 18, "dob": "21/04/1978", "prima": "mathew", "gender": "m", hair_colour: "maro", "ultima": "setter", "naționalitate": "australian", "ocupație": "dezvoltator" "_id": ObjectId ("4ef224bf0fec2806da6e9b2b"); "22:15", "prima": "jamie lee", "gen": "f", "hair_colour": "maro" : "actor" "_id": ObjectId ("4ef224bf0fec2806da6e9b2d"), "vârstă": 33, "dob": "09/12/1934" f "," hair_colour ":" alb "," ultima ":" dench "," naționalitate ":" engleză "," ocupație ":" actriță "

$ Gt / $ gte

Acum, să găsim toți actorii care sunt mai vechi de 47. Rulați următoarea interogare pentru a găsi lista respectivă:

 db.nettuts.find ('vârsta': '$ gt': 47);

Veți obține următoarele rezultate:

 "_id": ObjectId ("4ef224bf0fec2806da6e9b29"), "vârstă": 65, "dob": "03/06/1925", "prima": "arnold", "gender": "m", hair_colour: "maro", "ultima": "schwarzenegger", "naționalitate": "american", "ocupație": "actor"

Ce despre incluzând 40?

 db.nettuts.find ('vârsta': '$ gte': 47);

Întrucât există o singură persoană peste 47 de ani, datele returnate nu se schimbă.

$ În / $ nin

Cum despre găsirea informațiilor pe baza unei liste de criterii? Aceste prime au fost ok, dar, probabil, destul de banale. Să vedem acum care dintre oamenii pe care îi avem sunt fie actori, fie dezvoltatori. Cu următoarea interogare, vom afla că afară (pentru a face puțin mai ușor de citit, am limitat cheile care sunt returnate doar la numele și prenumele):

 db.nettuts.find ('ocupație': '$ in': ["actor", "dezvoltator"], "prima": 1, "ultima": 1);

Această interogare generează următoarea ieșire:

 "_id": ObjectId ("4ef224bf0fec2806da6e9b27"), "prima": "matthew", "last": "setter" ":" caan " " _id ": ObjectId (" 4ef224bf0fec2806da6e9b29 ")," prima ":" arnold "," last ":" schwarzenegger " " _id ": ObjectId (" 4ef224bf0fec2806da6e9b2a "); "", "ultim": "curtis" "_id": ObjectId ("4ef224bf0fec2806da6e9b2b"), "first" ")," prima ":" michael "," last ":" caine "

Puteți vedea că putem obține inversul acestui lucru folosind $ ninla fel de simplu.

Să facem asta mai distractiv și să combinăm unii dintre operatori. Să spunem că vrem să căutăm toți oamenii care sunt bărbați sau dezvoltatori, sunt mai puțin de 40 de ani.

Acum este un pic de gura, dar cu operatorii pe care i-am folosit pana acum - destul de usor de realizat. Să lucrăm prin ea și veți vedea. Aruncați o privire la interogarea de mai jos:

 db.nettuts.find ($ sau: ["gen": "m", "ocupație": "dezvoltator"], "vârstă": "$ gt": 40 , "ultim": 1, "ocupație": 1, "dob": 1);

Puteți observa că am stipulat că fie sexul poate fi de sex masculin, fie că ocupația poate fi un dezvoltator în $ sau condiție și apoi adăugați un și condiția vârstei fiind mai mare de 4 ani.

Pentru aceasta, obținem următoarele rezultate:

 "_id": ObjectId ("4ef22e522893ba6797bf8cb6"), "prima": "matthew", "last": "setter", "dob" _id ": ObjectId (" 4ef22e522893ba6797bf8cb9 ")," prima ":" tony "," last ":" curtis "," dob ":" 21/04/1978 "," ocupație ":" dezvoltator "

Expresii obisnuite

Acum sunt sigur că nu vei fi mulțumit de asta. Ți-am promis mai multă complexitate și funcționalitate avansată. Deci, să intrăm în folosirea unor expresii regulate. Să spunem că vrem să găsim utilizatorii care au un nume care începe cu 'ma' sau 'to' și numele ultimelor care încep cu 'se' sau 'de'. Cum am face asta??

Priviți următoarea interogare folosind o expresie regulată:

 db.nettuts.find ("prima": / (ma |) * / i, "ultima": / (se | de) / i);

Având în vedere că rezultatele vor fi:

 "_id": ObjectId ("4ef22e522893ba6797bf8cb6"), "prima": "matthew", "last": "setter", "dob": "21/04/1978" ":" maro "," ocupație ":" dezvoltator "," naționalitate ":" australian " " _id ": ObjectId (" 4ef22e532893ba6797bf8cbc " "dob": "09/12/1934", "sex": "f", "păr_color": "alb", "ocupație": "actriță", "naționalitate": "engleză"

Să privim cu atenție această interogare. În primul rând, realizăm un regex pe primul nume.

 "primul": / (ma |) * / i

// I indică faptul că efectuăm o regexă insensibilă la minuscule.

(Ma | a) * indică faptul că începutul șirului primului nume trebuie să fie "ma" sau "la".

Dacă nu sunteți familiar, * la final, se va potrivi ceva după aceea. Atunci când o puneți împreună, potrivim primele nume care au fie "ma" sau "to" la începutul lor. În regex pentru numele de familie, puteți vedea că am făcut același lucru, dar pentru numele de familie.

Nu prea sigur? Să încercăm un altul. Cum rămâne cu combinarea cu unul dintre operatorii condiționali. Să spunem că vrem să găsim toți oamenii cu numele de James sau Jamie care sunt actori feminini americani. Cum am face asta? Să vedem cum vom face mai jos:

 db.nettuts.find ("prima": / (jam? e *) * / i, "gen": "f", "ocupație": "actor", "naționalitate": "american");

Regexul de mai sus se va potrivi cu combinații cum ar fi: james, jamie, jamee etc. Semnul de întrebare se va potrivi cu un caracter, fie a-z, A-Z sau 0-9. Apoi, ca și până acum, * corespunde cu orice altceva care vine după e. De acolo, noi folosim operatorii condiționali pentru a limita în continuare rezultatele care vin înapoi. Trebuie remarcat faptul că, pe măsură ce folosim operatorul insensibil la minuscule, eu, interogările nu vor utiliza un index. Dar pentru scopurile acestui exemplu, este bine.

Rezultatul interogării de mai sus este:

 "_id": ObjectId ("4ef22e522893ba6797bf8cba"), "prima": "jamie lee", "last": "curtis" hair_colour ":" maro "," ocupație ":" actor "," naționalitate ":" american "

MapReduce

MapReduce este tatăl mare al analizei datelor. În cazul în care nu ați auzit de aceasta, MapReduce este un proces în care agregarea datelor poate fi împărțită și desfășurată într-un cluster de computere pentru a reduce timpul necesar pentru a determina un rezultat agregat dintr-un set de date.

Se compune din două părți: Hartă și Reduce. Harta creează lucrările care pot fi apoi livrate către nodurile lucrătorilor pentru a rula componenta Reduce. Reduce apoi calculează răspunsul pentru acea bucată de lucru care a fost exploatată la ea și returnează rezultatul care poate fi combinat cu celelalte bucăți pentru a forma răspunsul final.

Dacă doriți o descriere mai specifică, iată ce spune Wikipedia despre el:

MapReduce este un cadru pentru procesarea problemelor extrem de distribuite pe seturi de date uriașe folosind un număr mare de computere (noduri) denumite colectiv (dacă toate nodurile folosesc același hardware) sau o rețea (dacă nodurile utilizează hardware diferit). Procesarea computațională poate apărea pe datele stocate fie într-un sistem de fișiere (nestructurat), fie într-o bază de date (structurată).

"Hartă" pas: Nodul master ia intrarea, îl împarte în sub-probleme mai mici și le distribuie nodurilor lucrătorilor. Un nod muncitor poate face acest lucru din nou, la rândul său, conducând la o structură arborescentă pe mai multe nivele. Nodul muncitor procesează problema mai mică și transmite răspunsul la nodul principal.

"Reduce" pas: Nodul principal colectează apoi răspunsurile la toate sub-problemele și le combină într-un fel pentru a forma ieșirea - răspunsul la problema pe care încercase inițial să o rezolve.

Exemplu MapReduce

Să ne uităm la un exemplu simplu. Vom analiza setul nostru simplu de date și vom găsi numărarea totală a tuturor femelelor din grup. Desigur, acesta este un exemplu foarte simplist, dar va pune bazele înțelegerii, practic, a modului în care funcționează MapReduce.

Funcția de hartă

Aici vom crea o funcție de hartă care agregă informațiile din setul nostru de date prin sexul persoanei și emite un număr de 1 pentru fiecare dintre ele.

 var hartă = funcție () emit (gender: this.gender, count: 1); 

Aceasta va reveni la o ieșire similară cu următoarea:

 'f': 1

Funcția de reducere

Funcția de reducere va lua ieșirea din funcția hărții și o va folosi pentru a păstra un total de contorizare pentru fiecare gen. Aruncați o privire la funcția de reducere de mai jos.

 var reduce = funcție (cheie, valori) var rezultat = număr: 0; values.forEach (funcție (valoare) result.count + = value.count;) rezultat returnat; 

Executarea MapReduce

Acum, le-am pus împreună prin apelarea MapReduce funcția în baza noastră de date curentă. Trecem în Hartă și reduce variabilele pe care le-am creat anterior sunând la noi Hartă și reduce funcții și specificați numele colecției în care va fi stocat rezultatul; în acest caz 'sex'. Doar pentru a reitera, rezultatul chemării funcției MapReduce este o colecție în baza noastră de date curentă; că putem repeta exact așa cum am face orice altă colecție. Uitați-vă la codul de mai jos:

 var res = db.nettuts.mapReduce (hartă, reduce, out: 'gender');

Afișarea ieșirii

Când Map-Reduce este finalizat, îl putem accesa ca o colecție obișnuită, prin rularea găsifuncția pe care o facem mai jos.

 db.gender.find (); "_id": "sex": "f", "valoare": "count": 2 : 5

Aici, avem acum un total de funcționare pe gen; 2 pentru femele și 5 pentru bărbați - care se corelează cu setul nostru de date. Dar dacă am fi vrut să filtrezi femelele din grup. Ei bine, nu prea mult. Trebuie doar să folosim clauza de interogare pentru a ne permite să facem acest lucru. Norocos pentru noi, va arata familiar. Aruncați o privire la interogarea de mai jos.

 var res = db.nettuts.mapReduce (hartă, reduce, out: 'gender', interogare: "gender": "f");

Acum, când afișăm ieșirea, vom arăta mai jos:

 db.gender.find (); "_id": "sex": "f", "valoare": "count": 2

Există un număr de alți parametri pe care îi puteți trece la funcția de redirecționare a hărții pentru a personaliza mai mult ieșirea.

  • fel - sortați rezultatul returnat
  • limită - limita numărul de rezultate returnate
  • afară - numele colecției pentru stocarea rezultatelor
  • finalizarea - specificați o funcție care să funcționeze după finalizarea procesului de reducere
  • domeniu - specificați variabilele care pot fi utilizate în hartă, reduceți și definiți domeniul de aplicare al funcției
  • jsMode - Evită un pas intermediar (între hartă și reducere) de conversie înapoi în format JSON
  • prolix - urmări statisticile despre procesul de execuție

Lichidare

Aceasta a fost o acoperire de vârf a unor subiecte mai complexe ale lui mongoDB. Dar sper că ți se oferă mai mult un gust de ceea ce este posibil prin utilizarea acestui instrument minunat.

Am analizat operatorii condiționali: $ lt, $ gt, $ lte, $ gte, $ in, $ nin, $ nu și treceți printr-o introducere la MapReduce. Sper că ați scăpat mult de acest lucru și veți afla mai multe despre instrumentul excelent care este mongoDB.

Cod