MongoDB

De Cacauet Wiki
Salta a la navegació Salta a la cerca

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

  • Monogo shell:
    $ mongo
  • Seleccionar una db (o crear):
    > use <nom_db>
  • Mongo shell permet JavaScript. Creem una col·lecció de dades:
    > 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


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:

La operació de Update es pot resoldre de 2 maneres:

  1. 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}} )
  2. db.<col>.save( <doc> ) ...on <doc> ha de ser el nou document modificat amb el "_id" (PK) pertinent


Delete / Remove

Referències:


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ídeo de MongoDB University sobre indexes (segueix la sèrie de vídeos, hi ha diversos d'una durada de pocs minuts cadascun).

Per crear un índex (1 és ascendent i -1 descendent:

> db.<colleccio>.ensureIndex({<camp1>:1,<camp2>:-1,...}}

Per saber els índexes que té una col·lecció:

> db.<colleccio>.


Exercicis

...