Differences

This shows you the differences between two versions of the page.

Link to this comparison view

bd2:laboratoare:11 [2019/12/06 17:50]
ciprian.truica [Funcții]
— (current)
Line 1: Line 1:
-====== Laboratorul 11 - MongoDB ====== 
  
-===== Obiective ===== 
- 
-  * Comenzi MongoDB 
-  * Operații DML 
-  * Indexare 
-  * Funcții ​ 
-  * Agregarea datelor 
- 
- 
-===== Comenzi MongoDB =====  
- 
-==== Pornire MongoDB ==== 
- 
-Pentru a porni baza de date MongoDB se va folosi demonul **mongod**([[https://​docs.mongodb.com/​manual/​reference/​program/​mongod/​|mongod]]). 
- 
-Procesul demon **mongod** poate porni cu următorii paramterii: 
- 
-  * **''​-''''​-''​config <​filename>​** specifică un fisier de configurare 
-  * **''​-''''​-''​port <​port>​** pentru a specifica portul pe care asculta procesul demon, implicit 27017 
-  * **''​-''''​-''​bind_ip <​hostnames|ipaddresses|Unix domain socket paths>** pentru a specifica addresa de  
-  * **''​-''''​-''​dbpath <​path>​** calea către directorul unde se vor stoca fișierele de stocare. 
- 
-Exemplu utilizare **mongodb** 
- 
-<code bash> 
-mongod --port 27018 --bind_ip 192.100.10.10 --dbpath /data 
-</​code>​ 
- 
-<color red>Ex. 1.</​color>​ Să creeze un director pe discul ''​Student''​ numit ''​mongo_data''​. Să se pornească baza de date cu folosind ca director de stocare noul director creat. Restul valorilor rămân cele implicite. 
- 
-==== Conectare MongoDB ==== 
- 
-Pentru a va conecta la un server MongoDB, se folosește interpretorul în linie de comandă **mongo** ([[https://​docs.mongodb.com/​manual/​mongo/​|Documentație]]). 
- 
-Exemplu de utilizare: 
- 
-<code bash> 
-# se conectează implicit la localhost pe portul 27017 
-mongo 
- 
-# se conectează la hostname folosind portul implicit 217017 
-mongo --host hostname 
- 
-# se conectează implicit la localhost folosind portul port 
-mongo --port 27017 
- 
-# se conectează la hostname folosind portul port 
-mongo --host hostname:​27017 
- 
-mongo --host hostname --port 27017 
- 
-</​code>​ 
- 
-<color red>Ex. 2.</​color>​ Conectați-vă la MongoDB. 
- 
-==== Comenzi CLI MongoDB ==== 
- 
-Pentru a vedea baza de date curentă se folosește comanda **db**. 
- 
-Pentru a vedea toate bazele de date existente se folosește comanda **show dbs**. 
- 
-Pentru a vă conecta la o baza de date sau a crea o nouă bază de date se folosește comanda **use DATABASE_NAME**. În cazul în care se folosește comanda **use** pentru a crea o bază de date, aceasta va deveni persistentă numai dacă se crează o colecție sau se inserează o înregistrare. ​ 
- 
-Pentru a vedea toate colecțiile se folosește comanda **show collections**. 
- 
-Puteți folosi una din următoarele metode pentru a crea o nouă colecție: 
-  * **db.createCollection("​COLLECTION_NAME"​)**,​ unde **COLLECTION_NAME** este numele noii colecții 
-  * inserați o înregistrare și colecția se va crea automat. 
- 
-Pentru a șterge o colecție se folosește comanda **db.COLLECTION_NAME.drop()**. 
- 
-Pentru a șterge o baza de date se folosește comanda **db.dropDatabase()**. Trebuie să fiți conectați la baza de date (folosing **use**) pentru a o șterge. ​ 
- 
-<note important>​Numele bazelor de date este case sensitive.</​note>​ 
- 
-<color red>Ex. 3.</​color>​ Creați o bază de date numită **faculty** care să conțină colecția **students**. 
- 
- 
-===== Operații DML ===== 
- 
-==== Inserarea datelor ==== 
- 
-Pentru a adăuga date în MongoDB puteți sa folosiți una din metodele: 
- 
-  * Insert sau Bulk Insert ([[https://​docs.mongodb.com/​manual/​reference/​method/​db.collection.insert/​|Documentație]]) 
-  * **mongoimport** ([[https://​docs.mongodb.com/​manual/​reference/​program/​mongoimport/​|Documentație]]) 
- 
-=== insert() === 
- 
-Comanda Insert are următoare sintaxa 
- 
-<code javascript>​ 
-db.collection.insert( 
-   <​document or array of documents>,​ 
-   { 
-     ​writeConcern:​ <​document>,​ 
-     ​ordered:​ <​boolean>​ 
-   } 
-) 
-</​code>​ 
- 
-Un document dintr-o colecție este în format BSON: 
- 
-<code javascript> ​ 
-{ 
-    "​student": ​ 
-        { 
-            "​firstname":​ "​Ion", ​ 
-            "​lastname":​ "​Popescu"​ 
-        }, 
-    "​an":​ 4, 
-    "​grupa":​ "​342C3",​ 
-    "​materii": ​ 
-        [ 
-            {"​nume":​ "​BD2", ​ "​an":​ 4},  
-            {"​nume":​ "​Comp",​ "​an":​ 4},  
-            {"​nume":​ "​SO2", ​ "​an":​ 4} 
-        ], 
-    "​cunostinte":​ ["​SQL",​ "​Java",​ "​PL/​SQL"​] 
-} 
- 
-</​code>​ 
- 
-Pentru a insera documentul în colecția students: 
- 
-<code javascript> ​ 
-db.students.insert( 
-{ 
-    "​student": ​ 
-        { 
-            "​firstname":​ "​Ion", ​ 
-            "​lastname":​ "​Popescu"​ 
-        }, 
-    "​an":​ 4, 
-    "​grupa":​ "​342C3",​ 
-    "​materii": ​ 
-        [ 
-            {"​nume":​ "​Comp",​ "​an":​ 4},  
-        {"​nume":​ "​BD2"​ , "​an":​ 4},  
-            {"​nume":​ "​SO2"​ , "​an":​ 4} 
-        ], 
-    "​cunostinte":​ ["​SQL",​ "​Java",​ "​PL/​SQL"​] 
-} 
-) 
-</​code>​ 
- 
-Pentru a va ușura munca puteți sa va creați variabile la nivelul consolei. Dacă se dorește inserarea mai multor înregistrari,​ se poate declara un vector. ​ 
- 
-<code javascript> ​ 
-var stud = {"​student":​ { "​firstname":​ "​Andrei",​ "​lastname":​ "​Ionescu"​},​ "​an":​ 4, "​grupa":​ "​341C4",​ "​materii":​ [{"​nume":​ "​BD2",​ "​an":​ 4}, {"​nume":​ "​IA",​ "​an":​ 4},​{"​nume":​ "​IAUT",​ "​an":​ 4}], "​cunostinte":​ ["​C",​ "​C++",​ "​SQL"​] } 
-  
-db.students.insert(stud) 
- 
-var studs = [ 
-    {"​student":​ { "​firstname":​ "​George",​ "​lastname":​ "​Popescu"​},​ "​an":​ 4, "​grupa":​ "​341C2",​ "​materii":​ [{"​nume":​ "​BD2",​ "​an":​ 4}, {"​nume":​ "​IOCLA",​ "​an":​ 2}], "​cunostinte":​ ["​Python",​ "​SQL"​] ​ }, 
-    {"​student":​ { "​firstname":​ "​Georgiana",​ "​lastname":​ "​Petrescu"​},​ "​an":​ 4, "​grupa":​ "​341C2",​ "​materii":​ [{"​nume":​ "​BD2",​ "​an":​ 4}, {"​nume":​ "​SCAD",​ "​an":​ 4}], "​cunostinte":​ ["​Python",​ "​SQL"​] ​ }, 
-    {"​student":​ { "​firstname":​ "​Valentina",​ "​lastname":​ "​Vasilescu"​},​ "​an":​ 3, "​grupa":​ "​331CA",​ "​materii":​ [{"​nume":​ "​BD",​ "​an":​ 3}, {"​nume":​ "​RL",​ "​an":​ 3}, {"​nume":​ "​APD",​ "​an":​ 2}], "​cunostinte":​ ["​Java",​ "​C++",​ "​SQL"​] }, 
-    {"​student":​ { "​firstname":​ "​Grigore",​ "​lastname":​ "​Ionescu"​},​ "​an":​ 4, "​grupa":​ "​342C2",​ "​materii":​ [{"​nume":​ "​BD2",​ "​an":​ 4}, {"​nume":​ "​VLSI",​ "​an":​ 4}, {"​nume":​ "​SRIC",​ "​an":​ 4}, {"​nume":​ "​SO",​ "​an":​ 3}], "​cunostinte":​ ["​C",​ "​Python",​ "​SQL",​ "​Ruby"​] }, 
-    {"​student":​ { "​firstname":​ "​Andrei",​ "​lastname":​ "​Popescu"​},​ "​an":​ 3, "​grupa":​ "​332CA",​ "​materii":​ [{"​nume":​ "​CN1",​ "​an":​ 2}, {"​nume":​ "​CN2",​ "​an":​ 2}, {"​nume":​ "​RL",​ "​an":​ 3}], "​cunostinte":​ ["​C",​ "​Python",​ "​SQL",​ "​Ruby"​] }, 
-    {"​student":​ { "​firstname":​ "​Ana",​ "​lastname":​ "​Georgescu"​},​ "​an":​ 4, "​grupa":​ "​342C5",​ "​materii":​ [{"​nume":​ "​BD2",​ "​an":​ 4}, {"​nume":​ "​UBD",​ "​an":​ 4}, {"​nume":​ "​SRIC",​ "​an":​ 4}, {"​nume":​ "​SO",​ "​an":​ 3}], "​cunostinte":​ ["​C",​ "​Python",​ "​SQL",​ "​Ruby"​],​ "​sef":​ true }, 
-] 
- 
-db.students.insert(studs) 
-</​code>​ 
- 
-<color red>Ex. 4.</​color>​ Inserați în baza de date **faculty** în colecția **students** folosind structura JSON de mai sus doi colegi și pe dumneavoastră. 
- 
-=== **mongoimport** === 
- 
-Pentru a insera un fișier în format CSV sau JSON se folosește comanda **mongoimport**. 
-Parametrii comenzii sunt: 
-  * ''​-''''​-host=<​hostname><:​port>''​ - specifică numele host-ului și portul. Dacă nu se specifică se vor lua valorile implicite 
-  * ''​-''''​-port=<​port>''​ - specifică portul. Dacă nu se specifică se va lua valoarea implicită 
-  * ''​-''''​-db=<​databasename>''​ - specifică numele bazei de date unde se vor insera datele 
-  * ''​-''''​-collection=<​collection>''​ - specifică numele colecției care va stoca datele 
-  * ''​-''''​-fields=<​field1[,​field2]>''​ - specifică câmpurile din fișier care for fi inserate în colecție 
-  * ''​-''''​-columnsHaveTypes''​ - se utilizează dacă se dorește specificarea tipurilor de date pentru coloanele din lista de coloane specificată cu opțiunea ''​-''''​-fields''​ 
-  * ''​-''''​-type=<​json|csv|tsv>''​ -  specifică formatul fișierului cu date  
-  * ''​-''''​-file=<​filename>''​ - specifică numele fișierului cu date 
- 
- 
-<code bash> 
-mongoimport --host=192.100.10.2 --port=28018 --db=BD --collection=students --type=json --file=data_dump.json 
- 
-mongoimport --host=192.100.10.2 --port=28018 --db=BD --collection=students --columnsHaveTypes --fields="​name.string(),​birthdate.date(2006-01-02),​contacted.boolean(),​followerCount.int32(),​thumbnail.binary(base64)"​ --type=csv --file=data_dump.csv 
-</​code>​ 
- 
-<color red>Ex. 5.</​color>​ Să se insereze fișierul {{:​bd2:​laboratoare:​bd2_mongo.txt|bd2_mongo}} care conține baza de date în format JSON. Noua bază de date se va numi **BD2** și colecția se va numi **documents**. 
- 
- 
-==== Selectarea datelor ==== 
- 
-=== Select === 
- 
-În MongoDB operația de selecție a datelor este **find()** ([[https://​docs.mongodb.com/​manual/​reference/​method/​db.collection.find/​|Documentație]]). 
- 
-Sintaxa comenzii este: 
- 
-<code javascript>​ 
-db.collection.find(query,​ projection)​ 
-</​code>​ 
- 
-Unde 
-  * ''​query''​ reprezintă lista de filtre 
-  * ''​projection''​ reprezintă câmpurile care vor fi afișate 
- 
-Dacă parametrul ''​query''​ lipsește, atunci se selectează toate documentele. Dacă parametrul ''​projection''​ lipsește atunci se afișează toate câmpurile documentului. 
- 
-Comanda **find()** face paginație, arătând în consolă 10 înregistrări. 
- 
-Să se selecteze toți studenții din colecția **students**,​ baza de date **faculty** 
-<code javascript>​ 
-db.students.find() 
-</​code>​ 
- 
- 
-<note tip> 
-  * Dacă se dorește un întoarcerea unei singur document se folosește **findOne()** 
-<code javascript>​ 
-db.students.findOne() 
-</​code>​ 
- 
-  * Dacă se dorește un întoarcerea unui număr ''​n''​ de documente se folosește **limit(n)** 
-<code javascript>​ 
-db.students.find().limit(3) 
-</​code>​ 
- 
-  * Dacă se dorește sortarea rezultatelor după valoare unui anumit câmp se folosește ''​sort({label_1:​ order, label_2: order,..., label_n:​order})''​ unde ''​order''​ este ''​1''​ pentru ascendent și ''​-1''​ pentru descendent. 
- 
-<code javascript>​ 
-db.students.find().sort({"​grupa":​ 1}) 
-</​code>​ 
- 
-  * Dacă se dorește afișarea într-un mod citibil în consolă se folosește **pretty()** 
-<code javascript>​ 
-db.students.find().pretty() 
-</​code>​ 
- 
-  * **pretty**, **limit** și **sort** se pot folosi împreună 
- 
-<code javascript>​ 
-db.students.find().sort({"​student.firstname":​ 1}).limit(3).pretty() 
-</​code> ​ 
- 
-</​note>​ 
- 
-<color red>Ex. 6.</​color>​ Să se selecteze primele 4 rezultate ale unei cereri care întoarce toți studenți ordonați descrescător după nume. 
- 
- 
-=== Filtrarea cererilor === 
- 
-Pentru a filtra rezultatele se folosește parametru **query**. 
- 
-Pentru comparație avem: 
- 
-  * '':''​ - egalitate 
-  * ''​$ne''​ - diferit de (not equal) 
-  * ''​$gt''​ - mai mare 
-  * ''​$gte''​ - mai mare sau egal 
-  * ''​$lt''​ - mai mic 
-  * ''​$lte''​ - mai mic sau egal 
-  * ''​$in''​ - căutare într-o listă 
-  * ''​$all''​ - căutare cu egalitate pe toate elementele dintr-o listă 
- 
- 
-<code javascript>​ 
-db.students.find({"​student.firstname":​ "​Ion"​}) 
-db.students.find({an:​ {$gte: 4}}) 
-db.students.find({"​materii.nume":​ {$in: ['​SCAD',​ '​IA'​]} }) 
-db.students.find({"​grupa":​ /^341/ }) 
-db.students.find({"​cunostinte":​ {$all: [/^J/, /^C/ ]}}) 
-</​code>​ 
- 
-Operatori logici 
-  * ''​$or''​ - sau logic 
-  * ''​$and''​ - și logic 
-  * ''​$not''​ - negare logic 
- 
- 
-<code javascript>​ 
-db.students.find({$or: ​ [{"​student.lastname":​ "​Ionescu"​},​ {"​cunostinte":​ /^C/}]}) 
-db.students.find({$and:​ [{"​student.lastname":​ "​Ionescu"​},​ {"​cunostinte":​ /^C/}]}) 
-</​code>​ 
- 
-Operatori utili pentru vectori 
-  * ''​$size''​ pentru a verifica dimensiune 
-  * ''​0,​ 1, 2,​...''​ pentru poziționare (indexare vectorilor începe de la 0) 
- 
- 
-<code javascript>​ 
-db.students.find({"​cunostinte":​ {$size: 2}}) 
-db.students.find({"​cunostinte.2":​ "​SQL"​}) 
-db.students.find({"​materii.0.nume":​ "​BD2"​}) 
-</​code>​ 
- 
-Pentru a verifica existența unui câmp se folosește ''​$exists''​ 
-<code javascript>​ 
-db.students.find({"​sef":​ true}) 
-db.students.find({"​sef":​ {$exists: true}}) 
-db.students.find({"​sef":​ false}) 
-db.students.find({"​sef":​ {$exists: false}}) 
-</​code>​ 
- 
- 
-<note important>​Acești operatori pot să fie folosiți împreună.</​note>​ 
- 
-<color red>Ex. 7.</​color>​ Explicați ce fac cererile din acest subcapitol. 
- 
-<color red>Ex. 8.</​color>​ Să se selecteze toți studenții din anul 4 care au restanțe și știu limbajele de programare C și SQL. 
- 
-=== Proiecția === 
- 
-Pentru a proiecta doar anumite câmpuri se se folosește parametrul **projection**. ​ 
-În cazul în care nu se folosește filtrare se pun acolade fără goale pentru **query**. 
- 
-<code javascript>​ 
-db.students.find({},​ {"​student.firstname":​ 1}) 
-</​code>​ 
- 
-O cerere cu **projection** va întoarce doar câmpurile specificate și ''​_id''​. Dacă se dorește să se elimine câmpul ''​_id''​ atunci proiecția trebuie să conțină și ''"​_id":​ 0''​ 
- 
-<code javascript>​ 
-db.students.find({},​ {"​_id":​ 0, "​student.firstname":​ 1}) 
-</​code>​ 
- 
-<color red>Ex. 9.</​color>​ Să se selecteze studenții care nu sunt șefi și au cunoștințe de "​Python"​ pe a doua poziție din vectorul de cunoștințe. Afișați doar numele, prenumele și vectorul de cunoștințe. 
- 
-==== Modificarea datelor ==== 
- 
-Pentru a modifica datele se poate folosi una din comenzile: 
-  * ''​db.collection.update(<​query>,​ <​update>,​ <​options>​)​''​ ([[https://​docs.mongodb.com/​manual/​reference/​method/​db.collection.update/​|Documentație]]) 
- 
-Unde: 
-  * ''​query''​ - filtrează datele 
-  * ''​update''​ - setează date care trebuie modificate 
-  * ''​options''​ - diferite opțiuni, e.g.: 
-    * ''​upsert:​ <​boolean>''​ - crează un nou document în cazul în care nu se găsește nici un document cu filtrul 
-    * ''​multi:​ <​boolean>''​ -  modifică mai multe documente 
- 
-Pentru a seta o valoare se folosește ''​$set'':​ 
-<code javascript>​ 
-db.students.update({"​student.firstname":​ "​George"​},​ {$set: {"​grupa":​ "​342C1"​}}) 
-db.students.update({an:​ 4, "​student.firstname":​ "​Grigore"​},​ {$set: {cunostinte:​ ["​C++"​]}}) 
-</​code>​ 
- 
-Folosind set se suprascrie valoarea pentru câmp. În cazul în care dorim sa modificăm o structură de tip vector folosiți ''​$push''​. Dacă se dorește să se adauge mai multe valori, se poate folosi ''​$push''​ împreună cu ''​$each''​. 
-<code javascript>​ 
-db.students.update({an:​ 4, "​student.firstname":​ "​Grigore"​},​ {$push: {"​cunostinte":​ "​C"​}}) 
-db.students.update({an:​ 4, "​student.firstname":​ "​Grigore"​},​ {$push: {"​cunostinte":​{$each:​ ["​Python",​ "​SQL",​ "​Ruby"​]}}}) 
-</​code>​ 
- 
-Dacă se dorește să se modifice valoare unui element dintr-o listă sau a unui câmp dintr-un document imbricat care se găsește în listă se poate folosi ''​$''​. Trebuie să selectați și valoare/​câmpul care se dorește să fie modificat în ''​query'':​ 
-<code javascript>​ 
-db.students.update({"​student.firstname":​ "​Grigore",​ "​cunostinte":​ "​C"​},​ {$set: {"​cunostinte.$":​ "​Java"​}}) 
-db.students.update({"​student.firstname":​ "​Grigore",​ "​materii.nume":​ "​SRIC"​},​ {$set: {"​materii.$.nume":​ "​SPG"​}}) 
-db.students.update({"​student.firstname":​ "​Grigore",​ "​materii.nume":​ "​SPG"​},​ {$set: {"​materii.$.nume":​ "​SRIC",​ "​materii.$.an":​4}}) 
-</​code>​ 
- 
-<color red>Ex. 10.</​color>​ Să se adauge la toți studenți de anul 3 materiile EGC și LFA (nume si an) folosind o singură comandă. 
- 
- 
- 
-Alte funcții care modifică datele sunt: 
-  * ''​db.collection.updateOne(<​query>,​ <​update>,​ <​options>​)​''​ 
-  * ''​db.collection.updateMany(<​query>,​ <​update>,​ <​options>​)​''​ 
-  * ''​db.collection.updateMany(<​query>,​ <​update>,​ <​options>​)​''​ 
- 
- 
-==== Ștergerea datelor ==== 
-Pentru a șterge un document dintr-o colecție se folosește comanda: 
-  * ''​db.collection.remove(<​query>,​ <​justOne>​)​''​ [[https://​docs.mongodb.com/​manual/​reference/​method/​db.collection.remove/​|Documentație]] 
- 
-Unde 
-  * ''​query''​ - filtrează datele ​ 
-  * ''​justOne''​ -  boolean pentru a șterge unul (''​true''​) sau mai multe (''​false''​ -- implicit) documente 
- 
-<code javascript>​ 
- ​db.students.remove({"​an":​ {$lt: 4}}) 
-</​code>​ 
- 
-<note important>​ 
-Pentru a șterge toate documentele se folosește ''​db.collection.remove({})''​ 
-<code javascript>​ 
-db.students.remove({}) 
-</​code>​ 
-</​note>​ 
- 
-Alte comenzi care pot fi utilizare pentru a șterge documente dintr-o colecție sunt: 
-  * ''​db.collection.deleteOne(<​filter>​)​''​ 
-  * ''​db.collection.deleteMany(<​filter>​)​''​ 
- 
-<color red> Ex. 11.</​color>​ Să se șteargă doar un student care are materia BD2. 
- 
-===== Indexare ===== 
- 
-MongoDB suport diferite tipuri de indecși. Indecși sunt utilizați pentru a crește performanțele operațiilor de căutare. Indecși sunt creați la nivel de colecție. Pentru a crea un index se folosește comanda ''​createIndex()''​. La creare se specifică numele câmpului (i.e., ''​label''​) și modul de ordonare a indexului (i.e., ''​order''​) 
-  * Indecși simpli ''​db.collection.createIndex({"​label":​ order})''​ 
-  * Indecși compusi ''​db.collection.createIndex({"​label_1":​ order_1, "​label_2":​ order_2, ...})''​ 
-  * Indecși pe documente imbricate: ''​db.collection.createIndex({"​label_1.nested_label":​ order_1, "​label_2.nested_label":​ order_2, ...})''​ 
-  * Indecși geo-spațiali ''​db.collection.createIndex({"​label_1.nested_label":​ "​2d"​})''​ 
-  * Indecși textuali (o colecție poate să aibă un singur index textual, dar acesta poate fi compus)''​db.collection.createIndex({"​label_1":​ "​text",​ "​label_2":​ "​text",​ ...})''​ 
-  * Indecși hashed (utili pentru sharding): ''​db.collection.createIndex({"​label":​ "​hashed"​})''​ 
- 
-Pentru următoarele exemple conectați-vă la baza de date **BD2** creată anterior cu **mongoinport**. ​ 
- 
-<color red>Ex. 12.</​color>​ Analizați schema documentelor și înțelegeți structura 
- 
-<code javascript>​ 
-db.documents.createIndex({author:​ 1}) 
-db.documents.createIndex({gender:​ 1, age: 1}) 
-db.documents.createIndex({"​words.word":​ 1}) 
-db.documents.createIndex({"​geoLocation":​ "​2d"​}) 
-db.documents.createIndex({"​lemmaText":​ "​text"​}) ​ 
-db.documents.createIndex({"​date":​ "​hashed"​}) 
-</​code>​ 
- 
-<color red>Ex. 13.</​color>​ Descrieți tipul indecșilor construiți anterior. 
- 
-<note important>​ 
-Pentru a vedea toți indecși se folosește comanda ''​db.collection.getIndexes()''​ 
- 
-Pentru a șterge un index se folosește comanda ''​db.collection.dropIndexes("​index_name"​)''​ 
- 
-Pentru a șterge toți indecși (cu excepția indexului de pe cheia primară) se folosește comanda ''​db.collection.dropIndexes()''​ 
-</​note>​ 
- 
-==== Utilizare indecși geo-spațiali ==== 
- 
-  * Pentru a găsi documentele de lângă un punct ''​p=[x,​ y]''​ se folosește ''​$near''​ 
-  * Pentru a găsi documentele care se găsesc în diferite figuri geometrice se folosește ''​$within'':​ 
-    * Pentru un cerc cu centrul într-un punct ''​p=[x,​ y]''​ și o rază ''​r''​ se folosește ''​$center''​ 
-    * Pentru un dreptunghi definit prin punctele din stânga jos și dreapta sus se folosește ''​$box''​ 
-    * Pentru un poligon dat de o listă puncte se folosește ''​$polygon''​ 
- 
-<code javascript>​ 
-db.documents.find( { geoLocation:​ { $near: [25, 25] } }, {geoLocation:​ 1} ) 
-db.documents.find( { geoLocation:​ { $within: { $center: [[25, 10], 3] } } }, {geoLocation:​ 1} ) 
-db.documents.find( { geoLocation:​ { $within: { $box: [[25, 40], [30, 45]] } } }, { geoLocation:​ 1 } ) 
-db.documents.find( { geoLocation:​ { $within: { $polygon: [[20, 40], [40, 50], [30, 30]] } } },  { geoLocation:​ 1 } ) 
-</​code>​ 
- 
-==== Utilizare indecși textuali ==== 
- 
-Pentur a utiliza un index textual se folosește următoare sintaxă: 
-<code javascript>​ 
-{ 
-  $text: 
-    { 
-      $search: <​string>,​ 
-      $language: <​string>,​ 
-      $caseSensitive:​ <​boolean>,​ 
-      $diacriticSensitive:​ <​boolean>​ 
-    } 
-} 
-</​code>​ 
- 
-Unde 
-  * ''​$search''​ - este șirul de cuvinte căutat sau fraza căutată 
-  * ''​$language''​ - este limba pentru cuvintele căutate 
-  * ''​$caseSensitive''​ - dacă se caută case sensitive sau nu 
-  * ''​$diacriticSensitive''​ - dacă se ține cont de diacritice sau nu 
- 
- 
-<code javascript>​ 
-# Caută un cuvânt 
-db.documents.find( { $text: { $search: "​coffee",​ $language: "​english",​ $caseSensitive:​ false, $diacriticSensitive:​ false } } ,  { lemmaText: 1 } ) 
- 
-# Caută mai multe cuvinte (se folosește operatorul or) 
-db.documents.find( { $text: { $search: "​coffee cup", $language: "​english",​ $caseSensitive:​ false, $diacriticSensitive:​ false } } ,  { lemmaText: 1 } ) 
- 
-# Caută o frază 
-db.documents.find( { $text: { $search: "​\"​heaven tonight\"",​ $language: "​english",​ $caseSensitive:​ false, $diacriticSensitive:​ false } } ,  { lemmaText: 1 } ) 
- 
-# Caută o frază cu un scor de relevanță 
-db.documents.find( { $text: { $search: "​\"​heaven tonight\"",​ $language: "​english",​ $caseSensitive:​ false, $diacriticSensitive:​ false } } ,  { score: { $meta: "​textScore"​ }, lemmaText: 1, _id: 0}) 
-</​code>​ 
- 
-<color red>Ex. 14.</​color>​ Să se găsească toate documentele care se află într-un dreptunghi dat de punctele ''​[20,​ -100]''​ și ''​[40,​ 90]'',​ care să conțină cuvintele **tech** și **engineering**. Cererea să se folosească de indexul textual. Afișeți câmpul **rawText**. Să se refacă cererea utilizând alt câmp din document. 
- 
-===== Funcții ===== 
- 
-MongoDB permite dezvoltatorilor sa scrie funcții folosind limbajul JavaScript. 
- 
-<color red>Ex. 15.</​color>​ Să se scrie o funcție care primește un **query** pentru filtrare și împarte **lemmaText** în cuvinte. Funcția va întoarce un vector. 
- 
-<code javascript>​ 
-tokenization = function(q){ 
-    var cursor = db.documents.find(q,​{"​_id":​ 0, lemmaText: 1}); 
-    var tokens = Array(); 
-    cursor.forEach(function(elem){ 
-        tokens = tokens.concat(elem["​lemmaText"​].split("​ ")); 
-    }); 
-    return tokens; 
-} 
- 
-// utilizate 
-var q = {gender: "​male"​} 
-tokens = tokenization(q) 
- 
-</​code>​ 
- 
-<color red>Ex. 16.</​color>​ Să se scrie o funcție numită **countWords** care primește un **query** pentru filtrare și numără aparițiile unui cuvânt. Funcția va întoarce un obiect de forma ''​{word_1:​ count, word_2: count, ...}''​. Folosiți funcția ''​tokenization''​. 
- 
- 
-===== Funcții stocate ===== 
- 
-Funcțiile pot fi stocate la nivelul MongoDB. Pentru acest lucru se folosește o colecție specială numită ''​system.js''​. Stocarea se face cu comanda: ''​db.system.js.save(_id:​ "​function_name",​ value: "​function_body"​)''​. Pentru a lucra cu funcțiile stocare (a le încărca în sesiune) se folosește comanda ''​db.loadServerScripts()''​. 
- 
-<code javascrit>​ 
-db.system.js.save( 
-   { 
-     _id: "​tokenization",​ 
-     value : function(q){ 
-                var cursor = db.documents.find(q,​{"​_id":​ 0, lemmaText: 1}); 
-                var tokens = Array(); 
-                cursor.forEach(function(elem){ 
-                    tokens = tokens.concat(elem["​lemmaText"​].split("​ ")); 
-                }); 
-                return tokens; 
-            } 
-   } 
-) 
- 
-db.loadServerScripts() 
-</​code>​ 
- 
-<color red>Ex. 17.</​color>​ Salvați și apoi încărcați în sesiune funcția **countWords**. 
- 
-===== Agregarea datelor ===== 
- 
-În MongoDB putem să agregăm datele folosind mai multe metode: 
-  * Funcții de agregare 
-  * Modulul nativ de Aggregation Pipeline 
-  * MapReduce 
- 
-==== Funcții de agregare ==== 
- 
-MongoDB oferă utilizatorilor două funcții pentru agregare: 
- 
-1. Count: ''​db.collection.count(query)''​ 
- 
-<code javascript>​ 
-// Cate documente au lungimea textului lematizat 10 
-db.documents.count({lemmaTextLength:​ 10}) 
-</​code>​ 
- 
- 
-2. Distinct: db.collection.distinct(field,​ query)​ 
- 
-<code javascript>​ 
-// afiseaz varstele distincte 
-db.documents.distinct("​age"​) 
- 
-// afiseaz varstele distincte pentru female 
-db.documents.distinct("​age",​ {gender: "​female"​}).sort() 
-</​code>​ 
- 
-<color red>Ex. 18.</​color>​ Afișați toate cuvintele distincte. Folosiți câmpul **words**. 
- 
-==== Aggregation Pipeline ==== 
- 
-Pentru agregare, MongoDB oferă și **Aggregation Pipeline** ([[https://​docs.mongodb.com/​manual/​core/​aggregation-pipeline/​|Documentație]]). 
- 
-<code javascript>​ 
-db.collection.aggregate( 
-    { $match: <​query>​ }, 
-    { $unwind: <​array>​ }, 
-    { $project: <​projection>​},​ 
-    { $group: <​aggregation_group,​ aggregation_functions>​ }, 
-    { $sort: <​sorting_fields>​ }, 
-)​ 
-</​code>​ 
- 
-Unde: 
-  * $match - filtrează documentele de intrare după un **query** 
-  * $unwind - procesează elementele unui vector 
-  * $project - proiecția 
-  * $group - face grupuri și a aplica funcții agregare 
-  * $sort - reordonează documentele de intrare după o cheie 
- 
-<note important>​Contează ordinea în care sunt folosiți operatorii.</​note>​ 
- 
-<color red>Ex. 19.</​color>​ Să se utilizeze Aggregation Pipeline pentru a calcula numărul de apariții ale cuvintelor. 
- 
-<code javascript>​ 
-db.documents.aggregate([ 
-    { $match: q }, 
-    { $project: { words: { $split: ["​$lemmaText",​ " "]}}}, 
-    { $unwind: "​$words"​ }, 
-    { $group: { _id: "​$words",​ counts: { $sum: 1 } } } 
-]) 
-</​code>​ 
- 
-<color red>Ex. 20.</​color>​ Să se utilizeze Aggregation Pipeline pentru a calcula numărul de apariții ale cuvintelor folosind coloana **words**. 
- 
-==== MapReduce ==== 
- 
-MongoDB oferă un framework de MapReduce. Pentru a utiliza acest framework trebuie să scriem două funcții,​i.e.,​ Map și Reduce. ​ 
-Pentru a utilza funcțiile pe o colecție se folosește ''​mapReduce''​ ([[https://​docs.mongodb.com/​manual/​core/​map-reduce/​|Documentație]]):​ 
- 
- 
-<code javascript> ​ 
- 
-db.collection.mapReduce( 
-    mapFunction, ​ 
-    reduceFunction, ​ 
-    { 
-        finalize: <​function>,​ 
-        out: <​output>,​ 
-        query: <​document>,​ 
-        sort: <​document>,​ 
-        limit: <​number>,​ 
-        scope: <​document>​ 
-    } 
-) 
-</​code>​ 
- 
-Unde: 
-  * mapFunction - funcția de map 
-  * reduceFunction - funcția de reduce 
-  * finalize - (opțional) funcție pentru finalizare, se aplică după ce se termină procesul și datele sunt agregate 
-  * out -  (opțional) colecția unde va fi salvat rezultatul 
-  * query -  (opțional) filtru pentru documentele de intrare 
-  * sort - (opțional) ordonează documentele de intrare după cheie 
-  * limit - (opțional) limitează numărul de documente de intrare 
-  * scope -  (opțional) variabile din exterior care pot fi folosite în funcțiile map, reduce și finalize 
- 
-Comanda ''​mapReduce''​ este o mapare peste comanda **mapReduce** din MongoDB ([[https://​docs.mongodb.com/​manual/​reference/​command/​mapReduce/​|Documentație]]) 
- 
-<code javascript>​ 
-db.runCommand( 
-    { 
-        mapReduce: <​collection>,​ 
-        map: <​function>,​ 
-        reduce: <​function>,​ 
-        finalize: <​function>,​ 
-        out: <​output>,​ 
-        query: <​document>,​ 
-        sort: <​document>,​ 
-        limit: <​number>,​ 
-        scope: <​document>​ 
-    } 
-) 
-</​code>​ 
- 
- 
-<color red>Ex. 21.</​color>​ Să se utilizeze MapReduce pentru a calcula numărul de apariții ale cuvintelor. 
- 
-<code javascript>​ 
-mapFunction = function() { 
-    var tokens = this.lemmaText.split("​ "); 
-    for (var idx=0; idx<​tokens.length;​ idx++){ 
-        emit(tokens[idx],​ 1); 
-    } 
-} 
-    ​ 
-reduceFunction = function(key,​ values) { 
-    return Array.sum(values);​ 
-}; 
-  ​ 
-var q = {"​gender":​ "​female"​} ​       
-db.documents.mapReduce(mapFunction,​ reduceFunction,​ {query: q, out: "​wordCounts"​});​ 
- 
-db.wordCounts.count() 
- 
-db.wordCounts.find({"​_id":​ "​0"​}) 
- 
-db.wordCounts.drop() 
-</​code>​ 
- 
-<color red>Ex. 22.</​color>​ Să se utilizeze MapReduce pentru a calcula numărul de apariții ale cuvintelor folosind câmpul **words**. 
bd2/laboratoare/11.1575647432.txt.gz · Last modified: 2019/12/06 17:50 by ciprian.truica
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0