Omet navegació

3.3.3.8 - Upsert

Aquesta paraula ja l'havíem comentada en un punt anterior.

En el update() normal, si la condició de búsqueda no donava cap resultat (parlant ràpid, si no feis matching amb cap document), doncs no actualitzava cap document i punt.

El Upsert és una variant de l'update, que quan no coincidesca cap document amb la condició, crearà un document nou que serà el resultat de combinar el criteri que s'ha utilitzat en la condició amb les operacions d'actualització fetes en el segon paràmetre

Per a que un Update actue d'aquesta manera, li hem de posar un tercer paràmetre amb el valor true:

update ( {...} , {...} , true )

Recordeu que el primer paràmetre era la condició, i el segon l'actualització.

Mirem-ho en l'exemple dels alumnes. Si anem a actualitzar els cognoms, i es troba el document, s'actualitzarà:

> db.alumnes.update( { nom:"Abel" } , { $set : { cognoms : "Bernat Cantera" } } , true )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Efectivament, ens diu que ha modificat un document.

Però si no es troba el document (per exemple perquè li hem posat el nom Berta):

> db.alumnes.update( { nom:"Berta" } , { $set : { cognoms : "Bernat Cantero" } } , true )
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("56dfdbd136d8b095cb6bd57a")
})

Ja ens avisa que no ha fet cap matching, i ha fet un Upsert. Ho podem comprovar mirant tots els document de la col·lecció:

> db.alumnes.find()
{ "_id" : ObjectId("56debe3017bf4ed437dc77c8"), "nom" : "Abel", "cognoms" : "Bernat Cantera", "edat" : 22, "adreça" : { "carrer" : "Major", "numero" : 7, "cp" : "12502" }, "nota" : [ 9.5, 9 ] }
{ "_id" : ObjectId("56dfdbd136d8b095cb6bd57a"), "nom" : "Berta", "cognoms" : "Bernat Cantero" }
>

El nou documenttindrà els camps:

  • _id , amb el que ens havia avisat que generaria
  • Els camps de la condició, que en el nostre exemple és { nom:"Berta" }
  • Els camps de l'actualització, que en el nostre exemple eren els cognoms