Diferència entre revisions de la pàgina «MongoDB»
Línia 39: | Línia 39: | ||
* Seleccionar una db (o crear):<pre>> use <nom_db></pre> | * Seleccionar una db (o crear):<pre>> use <nom_db></pre> | ||
− | |||
− | |||
*Exemple amb dades: | *Exemple amb dades: | ||
Línia 46: | Línia 44: | ||
* Importar-lo:<pre>$ mongoimport -d students -c grades < grades.ef42a2b3e7ff.js</pre> | * Importar-lo:<pre>$ mongoimport -d students -c grades < grades.ef42a2b3e7ff.js</pre> | ||
*... | *... | ||
+ | |||
+ | === JavaScript en la Mongo Shell === | ||
+ | Això ens facilita molt la creació i manipulació de les dades. Per exemple, per crear un munt de documents que continguin un "num" i una "cosa" a triar aleatòriament entre "tablet", "smartphone" i "xocolata": | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | for (i=0;i<100000;i++) { | ||
+ | db.coses.save( { | ||
+ | "num":i, | ||
+ | "cosa": ["tablet","smartphone","xocolata"][Math.floor(Math.random()*3)] | ||
+ | }) | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Un altre exemple: | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | for (i=0;i<1000;i++) { | ||
+ | names=["examen","treball","questionari"]; | ||
+ | for(j=0;j<3;j++) { | ||
+ | db.notes.insert({ | ||
+ | "estudiant":i, | ||
+ | "tipus": names[j], | ||
+ | nota : Math.round(Math.random()*100) | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
<br> | <br> |
Revisió del 21:23, 17 des 2013
Contingut
Intro No-SQL
Algunes característiques:
- Treballem amb documents.
- La inconsistència de dades deixa de ser una prioritat.
- Treballem amb incrustació (embedding). Exemple de blog: posts+comments
- Dades relatives al document incrustades en el mateix (exemple de blog amb post+comment). Això ajuda a mantenir certa consistència.
- Millora la velocitat d'accés (performance). Latència dels discs alta (1ms) però ample de banda alt (BW).
- No té FKs. En canvi té operacions atòmiques.
- No té transaccions (consistència temporal). Alternatives:
- Reestructurar la nosta BBDD per treballar en un sol tipus de document (schema).
- Implementar-la en el nostre software.
- Tolerar certa inconsistència temporal (dependrà del tipus d'aplicació).
- Relacions:
- 1:1 millor sempre unir-les en un sol doc a no ser que excedeixi 16 MB (maxim).
- 1:N si "N" son molts millor apuntar dels molts al 1 (amb el _id). També es pot fer al revés amb una llista.
- Hi ha una variant típica de 1:pocs que és el cas que ens agrada per incrustar.
- N:N (molts:molts) calen llistes (es poden posar a les 2 col·leccions tot i que això significa que la app ha de controlar la consistència
- Sempre intentem incrustar docs.
Info:
- Schemaless and document based
- No joins, no SQL
- RDBS is not scalability in general machines
- memcache is not highly functional but scales well
- Joins don't scale well
- Documents have a 16 MB limit on 32 bit OS's
- Transactions are unavailable
- Crud Operations exists as wire protocols
- 'id' is immutable, and made up of Current Time, Machine Id, Process ID and global Counter
- remove is not an isolated transaction.
Primeres passes
- Instal·lar darrera versió (2.4.8) a Ubuntu:
- Monogo shell:
$ mongo
- Seleccionar una db (o crear):
> use <nom_db>
- Exemple amb dades:
- Importar-lo:
$ mongoimport -d students -c grades < grades.ef42a2b3e7ff.js
- ...
JavaScript en la Mongo Shell
Això ens facilita molt la creació i manipulació de les dades. Per exemple, per crear un munt de documents que continguin un "num" i una "cosa" a triar aleatòriament entre "tablet", "smartphone" i "xocolata":
for (i=0;i<100000;i++) {
db.coses.save( {
"num":i,
"cosa": ["tablet","smartphone","xocolata"][Math.floor(Math.random()*3)]
})
}
Un altre exemple:
for (i=0;i<1000;i++) {
names=["examen","treball","questionari"];
for(j=0;j<3;j++) {
db.notes.insert({
"estudiant":i,
"tipus": names[j],
nota : Math.round(Math.random()*100)
});
}
}
CRUD
Create Read Update Delete
- En Mongo Shell: http://docs.mongodb.org/manual/reference/crud/
- En PyMongo: http://api.mongodb.org/python/current/api/pymongo/collection.html
Create / Insert / Save
Per crear documents dins d'una col·lecció:
> db.<coleccio>.save( <JSON_obj> )
Read / Select / Find
La operació de query més estàndard en MongoDB és FIND. Alguns exemples:
> db.<coleccio>.findOne() > db.<coleccio>.findOne( {"tipus":"examen"} ) > db.<coleccio>.find() > db.<coleccio>.find( {estudiant:103} )
OJU: en Pymongo és find_one enlloc de findOne
Si ho volem veure una mica més ben formatat:
> db.<col>.find().pretty()
El 2n argument és per seleccionar camps (i excloure):
> db.<col>.find( {"tipus":"examen",nota:50}, {"estudiant":true,"_id":false} )
Operadors: estudiants amb examens amb notes > 90
> db.<col>.find( {"tipus":"examen", nota: {$gt:90} }, {"estudiant":true,"_id":false} )
Estudiants amb notes entre 65 i 71: db.grades.find( {"type":"exam",score: {$gte:65,$lte:71}} ).sort({"score":1})
Altres operadors: http://docs.mongodb.org/manual/reference/operator/query/
TODO: Unir dues queries amb $or...
Ordenar resultats (sort): http://docs.mongodb.org/manual/reference/method/cursor.sort/
Update
Referències:
- Mongo Shell Update: http://docs.mongodb.org/manual/tutorial/modify-documents/
- Pymongo Update: http://api.mongodb.org/python/current/api/pymongo/collection.html#pymongo.collection.Collection.update
- Update operators: http://docs.mongodb.org/manual/reference/operator/update/
La operació de Update es pot resoldre de 2 maneres:
- db.<col>.update( ... ) ...amb els següents operadors http://docs.mongodb.org/manual/reference/operator/update/#id1
- Exemple en mongo shell:
self.posts.update( {"_id":33}, {$addToSet:{"comments":comment}} )
- Exemple en pymongo:
self.posts.update( {"_id":33}, {"$addToSet":{"comments":comment}} )
- Exemple en mongo shell:
- db.<col>.save( <doc> ) ...on <doc> ha de ser el nou document modificat amb el "_id" (PK) pertinent
Delete / Remove
Referències:
- Pymongo remove: http://api.mongodb.org/python/current/api/pymongo/collection.html#pymongo.collection.Collection.remove
- ...
Indexes
Els indexes augmenten la velocitat de les consultes. Si no fos per ells, cada cop que fem una recerca (find) hauriem de repassar tota la BBDD, i si aquesta té una xifra elevada de registres (diguem-ne, 10 milions) la consulta serà lenta, i farà que el sistema sigui impracticable.
Vídeos de MongoDB University:
- Introducció als índexes (segueix la sèrie de vídeos, hi ha diversos d'una durada de pocs minuts cadascun).
- Un índex accelera les cerques
- El mateniment de l'índex alenteix les insercions.
- Índexes i performance (velocitat d'accés).
- findOne() és més ràpid perquè quan troba una mostra ja surt.
- si el ID que busquem és baix va ràpid (al principi de la col·lecció).
- Si el ID que busquem és alt triga més.
- find() triga igual perquè ha de buscar en tota la base de dades: lent (sense índex)
- Buscar un element que no existeix: triga molta estona.
- ...
Per crear un índex (1 és ascendent i -1 descendent):
> db.<colleccio>.ensureIndex({<camp1>:1,<camp2>:-1,...}}
Per saber els índexes de tot el sistema:
> db.system.indexes.find()
Per saber els índexes que té una col·lecció:
> db.<colleccio>.getIndexes()
Multi-indexes
Indexes sobre arrays, per ex:
{ tags: ["btt","tennis","futbol"],
categories: ["esports","hobbies"] }
Es poden crear índexes sobre un array, però no sobre 2 alhora:
> ensureIndex( {tags:1} ) OK > ensureIndex( {categories:-1} ) OK >ensureIndex( {tags:1, categories:-1} )NO ES POT
Posar un índex en un camp intern d'un document, per ex, en una col·lecció d'usuaris:
> ensureIndex( {adreces.telefons:1} )
(array d'adreces amb un camp telèfons incrustat)
Exercicis
...