back to top

MongoDB: Creare, aggiornare e rimuovere documenti da una collezione

In questa lezione vedremo come creare, aggiornare e rimuovere dei documenti da una collezione.

Prima di iniziare questa lezione, è bene evidenziare che per semplicità, per facilitare la lettura degli esempi e visto che la shell di MongoDB lo consente, i campi delle condizioni di filtro e dei documenti delle collezioni non sono racchiusi fra doppi apici. A voler essere rigorosi, i documenti devono essere in formato JSON e per questo tutti i campi dovrebbero essere racchiusi fra doppi apici.

insertOne() e insertMany()

Per inserire un documento usiamo il metodo db.collection.insertOne a cui passiamo come argomento il documento da aggiungere alla collezione.

var user = {
  name: 'Clara Luettgen',
  email: '[email protected]',
  address: '529 Shanahan Branch',
  bio: 'Consequatur veritatis itaque odit optio optio fugit reprehenderit ex.'
}
ecommerce> db.users.insertOne(user);
{
  acknowledged: true,
  insertedId: ObjectId("62223853d5c3e1f2c45ade67")
}

È importante soffermarci un attimo per fare delle considerazioni. Innanzitutto se non indichiamo un campo ‘_id’, MongoDB ne aggiunge automaticamente uno di tipo ObjectId che consente di ottenere identificativi univoci di 12 byte. Sulla documentazione ufficiale trovate maggiori dettagli su come viene generato un valore di tipo ObjectId.

Ogni documento in MongoDB deve contenere un campo ‘_id’. All’interno di una collezione non possono esistere 2 documenti con lo stesso ‘_id’. Facendo riferimento all’esempio visto sopra, se proviamo ad inserire nuovamente lo stesso documento (privo del campo ‘_id’), non riceviamo alcun messaggio di errore. È vero che al metodo db.users.insertOne() passiamo lo stesso documento, ma dal momento che non è presente un campo ‘_id’, MongoDB provvede a generarne uno diverso. Al contrario, se proviamo ad inserire il documento mostrato sotto, anche se gli altri campi sono differenti, riceveremo un messaggio di errore perché abbiamo usato lo stesso valore di _id del documento inserito in precedenza.

{
    _id: ObjectId("62223853d5c3e1f2c45ade67"),
    name: 'Taylor Hickle',
    email: '[email protected]',
    address: '28109 Abshire Drive',
    bio: 'Sint quia aliquid iure non.'
}

MongoServerError: E11000 duplicate key error collection: 
ecommerce.users 
index: _id_ 
dup key: { _id: ObjectId('62223853d5c3e1f2c45ade67') }

Il valore ‘_id’ può essere di qualsiasi tipo purché univoco. Possiamo anche definire un campo ‘_id’ per i nostri documenti ma dobbiamo assicurarci di non generare valori uguali. Per questo motivo è conveniente lasciare l’incarico a MongoDB.

Come abbiamo visto alla fine della precedente lezione, oltre al metodo db.collection.insertOne(), è disponibile anche db.collection.insertMany() a cui passiamo un array di documenti.

var users = [
  {
    name: 'Taylor Hickle',
    email: '[email protected]',
  },
  {
    name: 'Clara Luettgen',
    email: '[email protected]',
  },
  {
    name: 'Mr. Philip Kunde',
    email: '[email protected]',
  },
  {
    name: 'Bobby Spinka',
    email: '[email protected]',
  }
]

ecommerce> db.users.insertMany(users);

{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId("622240e1d5c3e1f2c45ade69"),
    '1': ObjectId("622240e1d5c3e1f2c45ade6a"),
    '2': ObjectId("622240e1d5c3e1f2c45ade6b"),
    '3': ObjectId("622240e1d5c3e1f2c45ade6c")
  }
}

Come secondo argomento, db.collection.insertOne() accetta un oggetto di opzioni. Una di queste è l’opzione booleana "ordered". Se è pari a true (valore predefinito), i documenti vengono inseriti nell’ordine in cui appaiono nell’array. Se uno dei documenti dell’array genera un errore in fase d’inserimento, i restanti documenti vengono scartati e non saranno inseriti nella collezione.

var users = [
  {
    _id: 0,
    name: 'Taylor Hickle',
    email: '[email protected]',
  },
  {
    _id: 1,
    name: 'Clara Luettgen',
    email: '[email protected]',
  },
  {
    _id: 2,
    name: 'Mr. Philip Kunde',
    email: '[email protected]',
  },
  {
    _id: 2,
    name: 'Bobby Spinka',
    email: '[email protected]',
  }
]

ecommerce> db.users.insertMany(users);

Uncaught:
MongoBulkWriteError: E11000 duplicate key error collection: ecommerce.users index: _id_ dup key: { _id: 2 }
Result: BulkWriteResult {
  result: {
    ok: 1,
    writeErrors: [
      WriteError {
        err: {
          index: 3,
          code: 11000,
          errmsg: 'E11000 duplicate key error collection: ecommerce.users index: _id_ dup key: { _id: 2 }',
          errInfo: undefined,
          op: { _id: 2, name: 'Bobby Spinka', email: '[email protected]' }
        }
      }
    ],
    writeConcernErrors: [],
    insertedIds: [
      { index: 0, _id: 0 },
      { index: 1, _id: 1 },
      { index: 2, _id: 2 },
      { index: 3, _id: 2 }
    ],
    nInserted: 3,
    nUpserted: 0,
    nMatched: 0,
    nModified: 0,
    nRemoved: 0,
    upserted: []
  }
}

Dall’esempio notiamo che solo i primi 3 documenti saranno inseriti, il quarto viene scartato.

Al contrario se il valore di ‘ordered‘ è uguale a false, i documenti non saranno inseriti in ordine ed eventuali errori generati da un documento non impediranno la scrittura dei restanti. Nell’esempio riportato sotto, anche se il secondo documento genera un errore di inserimento, verranno comunque aggiunti alla collezione i documenti successivi.

var users = [
  {
    _id: 0,
    name: 'Taylor Hickle',
    email: '[email protected]',
  },
  {
    _id: 0,
    name: 'Clara Luettgen',
    email: '[email protected]',
  },
  {
    _id: 1,
    name: 'Mr. Philip Kunde',
    email: '[email protected]',
  },
  {
    _id: 2,
    name: 'Bobby Spinka',
    email: '[email protected]',
  }
]

ecommerce> db.users.insertMany(users, {ordered: false})
Uncaught:
MongoBulkWriteError: E11000 duplicate key error collection: ecommerce.users index: _id_ dup key: { _id: 0 }
Result: BulkWriteResult {
  result: {
    ok: 1,
    writeErrors: [
      WriteError {
        err: {
          index: 1,
          code: 11000,
          errmsg: 'E11000 duplicate key error collection: ecommerce.users index: _id_ dup key: { _id: 0 }',
          errInfo: undefined,
          op: {
            _id: 0,
            name: 'Clara Luettgen',
            email: '[email protected]'
          }
        }
      }
    ],
    writeConcernErrors: [],
    insertedIds: [
      { index: 0, _id: 0 },
      { index: 1, _id: 0 },
      { index: 2, _id: 1 },
      { index: 3, _id: 2 }
    ],
    nInserted: 3,
    nUpserted: 0,
    nMatched: 0,
    nModified: 0,
    nRemoved: 0,
    upserted: []
  }
}

Aggiornare un documento con updateOne()

db.collection.updateOne() aggiorna un solo documento della collezione selezionato in base ad una condizione passata come primo argomento. Come per insertOne e insertMany, esiste il metodo updateMany() che aggiorna tutti i documenti di una collezione che soddisfano un dato criterio.

Per il momento concentriamoci su updateOne() perché le considerazioni e gli esempi che andremo a fare valgono anche per updateMany().

Il metodo updateOne() accetta un primo argomento filtro che rappresenta un criterio di selezione per individuare un documento della collezione. Il secondo argomento indica invece quali modifiche devono essere effettuate.

Vediamo subito un esempio, ma prima inseriamo nella collezione ‘users’ una serie di documenti con le informazioni relative ad alcuni utenti.

> var users = [
  {
    _id: 0,
    name: 'Taylor Hickle',
    email: '[email protected]',
    city: 'Milano',
    age: 44
  },
  {
    _id: 1,
    name: 'Clara Luettgen',
    email: '[email protected]',
    city: 'Bologna',
    age: 35
  },
  {
    _id: 2,
    name: 'Mr. Philip Kunde',
    email: '[email protected]',
    city: 'Lecce',
    age: 26
  },
  {
    _id: 3,
    name: 'Bobby Spinka',
    email: '[email protected]',
    city: 'Cagliari',
    age: 52
  }
]

> db.users.insertMany(users)

Definire il valore di un campo con l’operatore $set

Supponiamo di voler aggiornare la città di residenza dell’utente ‘Bobby Spinka’. Basterà usare il metodo updateOne() per modificare il valore del campo city come mostrato sotto.

> db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {$set: {city: 'Sassari'}}
)

{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

Nel precedente esempio, al metodo updateOne() passiamo un primo argomento per selezionare un documento della collezione users che deve essere aggiornato. Il primo documento della collezione che presenta un campo ‘name’ con valore ‘Bobby Spinka’ verrà modificato.

Se viene trovato un documento, modifichiamo il valore del campo ‘city’ usando l’operatore $set. Se il documento non presenta un campo ‘city’, l’operatore $set ne aggiunge uno nuovo con il valore indicato, ovvero ‘Sassari’. Nel caso specifico, è presente un campo ‘city’ nel documento relativo all’utente ‘Bobby Spinka’ per cui viene aggiornato e al termine dell’operazione avrà come valore ‘Sassari’.

Più in generale l’operatore $set rimpiazza il valore di un campo o aggiunge il campo se non è presente nel documento.

La sintassi da usare è la seguente:

{ $set: { <field1>: <value1>, ... } }

I documenti in MongoDB non hanno uno schema fisso. Grazie a questa flessibilità, nulla vieta di usare $set per aggiornare un campo e nello stesso tempo cambiare il tipo di valore.

Nell’esempio sottostante aggiorniamo il campo email che contiene un valore di tipo stringa. Al suo posto assegniamo un array di stringhe.

> db.users.updateOne(
  { name: 'Bobby Spinka' },
  { $set: { email: ['[email protected]', '[email protected]'] } }
)
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

L’operatore $set consente di modificare anche i campi di documenti annidati. Supponiamo di avere nella collezione users dei documenti come quello riportato sotto.

{
  "_id": {"$oid": "4212a891f29561a1dbcd24a7"},
  "name": "John Doe",
  "email": "[email protected]",
  "age": 44,
  "address": {
    "city": "Leeds",
    "street": "114, Wellington St",
    "postcode": "LS14LT"
  }
}

Se volessimo modificare i campi ‘street‘ e ‘postcode‘, possiamo usare ancora una volta l’operatore $set come mostrato nel frammento di codice riportato sotto.

> db.users.updateOne(
  { 'name': 'John Doe' },
  { 
    $set: { 
      'address.street': '72 Brudenell Rd', 
      'address.postcode': 'LS61EG'
    }
  }
)
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

Possiamo infatti utilizzare $set per modificare più campi contemporaneamente. Inoltre è bene notare che per i documenti annidati, i campi devono essere sempre racchiusi fra virgolette altrimenti riceveremo un messaggio di errore (es. 'address.street').

Se invece volessimo rimuovere l’intero campo ‘address’ e sostituirlo solo con un campo ‘city’, possiamo usare $set insieme a $unset. Quest’ultimo è un altro operatore di MQL (MongoDB Query Language) che permette di rimuovere un campo da un documento.

> db.users.updateOne(
  { 'name': 'John Doe' }, 
  { $unset: {'address': 1}, $set: { 'city': 'Leeds'} }
)

{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

In quest’ultimo esempio, modifichiamo il documento relativo all’utente ‘John Doe’ rimuovendo il campo ‘address’ che è un documento annidato e aggiungendo un campo ‘city’ di tipo stringa.

Incrementare il valore di un campo con l’operatore $inc

Un altro operatore utile è $inc che può essere utilizzato per incrementare o decrementare il valore di un campo esistente o per crearne uno nuovo se non esiste già.

La sintassi da usare è la seguente.

{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }

Per esempio possiamo incrementare l’età di un utente con la seguente query.

> db.users.updateOne({name: 'Bobby Spinka'}, {$inc: {age: 2}})

In questo modo abbiamo incrementato il campo ‘age’ di 2. Ma possiamo anche decrementarlo di 1 come mostrato sotto.

> db.users.updateOne({name: 'Bobby Spinka'}, {$inc: {age: -1}})

Aggiornare campi di tipo Array

MQL presenta vari operatori per lavorare su campi di tipo Array. Per appendere degli elementi ad un array, possiamo usare $push. Se l’array non esiste, viene prima creato.

La sintassi per $push è la seguente:

{ $push: { <field1>: <value1>, ... } }

Supponiamo di lavorare con la solita collezione di utenti. Possiamo aggiungere un campo ‘hobby’ di tipo Array che inizialmente non esiste ed inserire un primo elemento all’array come mostrato sotto.

> db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {$push: {'hobby': 'Fotografia'}}
)

Se volessimo aggiungere più elementi contemporaneamente ad un array, possiamo combinare $push con l’operatore $each:

> db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {
    $push: {
      hobby: {
        $each: ['Giardinaggio', 'Trekking']
      }
    }
  }
)

Già con questo esempio iniziamo a vedere come combinare più operatori e modificatori in MQL. Quella che si va a creare è una struttura annidata. In quest’ultimo caso, invece di passare un valore al campo ‘hobby’, assegniamo un nuovo documento in cui la chiave è il modificatore $each che accetta come valore un array.

Questo è uno dei motivi per cui nella precedente lezione abbiamo presentato vari strumenti per interrogare il database via linea di comando. Infatti quando si scrivono delle query complesse, può risultare difficile leggerle se non sono formattate su più righe.

Tornando a parlare di $push, questo continua ad appendere elementi all’array anche se dei valori sono già presenti. Se volessimo evitare duplicati ed aggiungere degli elementi solo se non sono già nell’array possiamo invece utilizzare l’operatore $addToSet. In questo modo l’array verrà trattato come una sorta di Set.

La sintassi per $addToSet è simile a quella dell’operatore $push e anche in questo caso possiamo combinarlo con $each. L’esempio seguente appende degli elementi all’array ‘hobby’ se non sono già presenti.

> db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {
    $addToSet: {
      hobby: {
        $each: ['Nuoto', 'Musica']
      }
    }
  }
)

Dopo aver visto come aggiungere degli elementi ad un array, soffermiamoci a parlare di due operatori che possiamo usare per rimuovere degli elementi da un array.

In particolare l’operatore $pop rimuove il primo o l’ultimo elemento di un array. {"$pop" : {"field" : -1}} rimuove il primo elemento dell’array associato al campo, se passiamo invece il valore 1 rimuoviamo l’ultimo elemento dell’array.

Supponiamo di avere un documento come quello riportato sotto.

{
    _id: 3,
    name: 'Bobby Spinka',
    email: [ '[email protected]', '[email protected]' ],
    city: 'Sassari',
    age: 52,
    hobby: [
      'Fotografia',
      'Giardinaggio',
      'Trekking',
      'Nuoto',
      'Musica'
    ]
  }

La seguente query rimuove ‘Musica’ dall’array ‘hobby’.

db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {$pop: {hobby: 1}}
)

Un altro operatore per rimuovere degli elementi è $pull che elimina da un array tutti i valori che soddisfano la condizione specificata.

La sintassi da usare è:

{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }

Facendo riferimento al solito documento, possiamo rimuovere ‘Giardinaggio’ e ‘Nuoto’ dall’array ‘hobby’ con la seguente query.

> db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {
    $pull: {
      hobby: {
        $in: ['Giardinaggio','Nuoto']
      }
    }
  }
)

Nell’esempio precedente abbiamo anche usato l’operatore $in per indicare che vanno eliminati dall’array ‘hobby’ tutti gli elementi che sono presenti nell’array passato come valore all’operatore $in.

Infine se volessimo modificare un elemento specifico di un array possiamo indicare l’indice dell’elemento usando una sintassi simile a quella che abbiamo utilizzato per i documenti annidati. Definiamo i vari livelli di annidamento separandoli dal carattere ‘.’. Per esempio per accedere al primo elemento dell’array ‘hobby’, useremo ‘hobby.0’ come campo del documento assegnato all’operatore $set.

> db.users.updateOne(
  {name: 'Bobby Spinka'}, 
  {
    $set: {'hobby.0': 'Tennis'}
  }
)

Con l’ultima query modifichiamo il valore del primo elemento dell’array ‘hobby’ sostituendolo con ‘Tennis’.

In generale se abbiamo più livelli di annidamento, possiamo accedere ad un certo campo annidato di un array o di un oggetto indicando una stringa di livelli separati dal carattere ‘.’.

Creare un documento se non esiste con l’opzione upsert

Sia db.collection.updateOne() che db.collection.updateMany() accettano un terzo argomento che è un documento di opzioni facoltativo.

Una delle opzioni particolarmente interessante è il campo booleano upsert il cui valore predefinito è false.

Se upsert è pari a true possono verificarsi due possibili casi:

  • se esiste un documento nella collezione che soddisfa la condizione filtro passata come primo argomento ad updateOne o updateMany(), si procede all’aggiornamento come visto negli esempi precedenti.
  • se non esiste nessun documento nella collezione che soddisfa la condizione filtro, viene creato un nuovo documento

Per esempio, la seguente query crea un nuovo documento con due campi ‘name’ uguale a ‘Laura Bianchi’ e ‘city’ pari a ‘Foligno’ perché non esiste ancora un documento nella collezione con un campo ‘name’ uguale a ‘Laura Bianchi’.

> db.users.updateOne(
  { name: 'Laura Bianchi' },
  { $set: { city: 'Foligno' } }, 
  {upsert: true}
)

{
  acknowledged: true,
  insertedId: ObjectId("622511c6196563d3b11351d2"),
  matchedCount: 0,
  modifiedCount: 0,
  upsertedCount: 1
}

Possiamo avere conferma dell’inserimento attraverso db.users.findOne() che restituisce un documento.

> db.users.findOne({name: 'Laura Bianchi'})
{
  _id: ObjectId("622511c6196563d3b11351d2"),
  name: 'Laura Bianchi',
  city: 'Foligno'
}

Ottenere la versione aggiornata di un documento con findAndModify()

Se invece volessimo aggiornare e recuperare contemporaneamente un documento di una collezione, possiamo affidarci al metodo db.collection.findAndModify() che può essere configurato in diverso modo attraverso una serie di opzioni.

Noi vedremo solo 3 dei possibili campi del documento di configurazione che db.collection.findAndModify() riceve come argomento.

I primi 2 sono query e update con cui indichiamo rispettivamente un criterio per selezionare un particolare documento e le modifiche da apportare al documento eventualmente trovato.

Per esempio possiamo recuperare dalla collezione users il documento relativo all’utente ‘Clara Luettgen’ ed incrementare allo stesso tempo il valore del campo ‘age’.

Il documento iniziale prima di eseguire la query è il seguente:

{
  _id: 1,
  name: 'Clara Luettgen',
  email: '[email protected]',
  city: 'Bologna',
  age: 35
}

Eseguiamo le modifiche con il metodo db.collection.findAndModify() che restituisce anche il documento sui cui sono stati effettuati gli aggiornamenti.

db.users.findAndModify(
  {
    query: {name: 'Clara Luettgen'}, 
    update: {$inc: {age: 1}}
  }
)

{
  _id: 1,
  name: 'Clara Luettgen',
  email: '[email protected]',
  city: 'Bologna',
  age: 35
}

Come possiamo notare, otteniamo in risposta lo stesso documento originale, ma se interroghiamo nuovamente il database ci accorgiamo che il documento è stato effettivamente aggiornato.

> db.users.findOne({name: 'Clara Luettgen'})
{
  _id: 1,
  name: 'Clara Luettgen',
  email: '[email protected]',
  city: 'Bologna',
  age: 36
}

Infatti il metodo db.collection.findAndModify() restituisce il documento già presente nella collezione prima di essere aggiornato, a meno che non passiamo un altro campo di configurazione, ovvero new con valore uguale a true.

Ripetiamo la query richiedendo che in questo caso venga restituito il documento dopo esser stato aggiornato.

> db.users.findAndModify(
  {
    query: {name: 'Clara Luettgen'}, 
    update: {$inc: {age: 1}},
    new: true
  }
)

{
  _id: 1,
  name: 'Clara Luettgen',
  email: '[email protected]',
  city: 'Bologna',
  age: 37
}

Aggiornare più documenti con updateMany()

Tutte le considerazioni fatte per db.collection.updateOne() valgono anche per db.collection.updateMany(). La differenza fra i due metodi sta nel fatto che il primo aggiorna solo 1 documento della collezione che soddisfa i criteri di selezione. Al contrario db.collection.updateMany() aggiorna tutti i documenti che soddisfano una certa condizione.

Supponiamo di ricreare nuovamente la collezione di utenti come mostrato sotto.

ecommerce> var users = [
  {
    _id: 0,
    name: 'Taylor Hickle',
    email: '[email protected]',
    city: 'Milano'
  },
  {
    _id: 1,
    name: 'Clara Luettgen',
    email: '[email protected]',
    city: 'Bologna'
  },
  {
    _id: 2,
    name: 'Mr. Philip Kunde',
    email: '[email protected]',
    city: 'Lecce'
  },
  {
    _id: 3,
    name: 'Bobby Spinka',
    email: '[email protected]',
    city: 'Cagliari'
  }
]

ecommerce> db.users.drop()

ecommerce> db.users.insertMany(users)

Ipotizziamo di voler aggiungere un ulteriore campo ‘fast_delivery’ per i soli clienti delle città di Milano e Bologna. Per aggiornare più documenti useremo db.collection.updateMany().

ecommerce> db.users.updateMany(
  {
    city: {
      $in: ['Milano', 'Bologna']
    }
  }, {$set: {fast_delivery: true}}
)

{
  acknowledged: true,
  insertedId: null,
  matchedCount: 2,
  modifiedCount: 2,
  upsertedCount: 0
}

Nell’esempio riportato sopra abbiamo usato di nuovo l’operatore $in che seleziona i documenti in cui il valore del campo specificato è uguale a uno degli elementi dell’array. Nel nostro caso selezioniamo tutti i documenti in cui il campo city è uguale a ‘Milano’ o ‘Bologna’.

Sostituire un documento con replaceOne()

Abbiamo visto come aggiornare i campi di un documento. Se invece volessimo rimpiazzarlo completamente potremmo utilizzare il metodo db.collection.replaceOne().

Il primo argomento rappresenta il criterio di selezione per individuare il documento da sostituire.

Il secondo argomento è invece il documento sostitutivo.

Supponiamo che la collezione users contenga il seguente documento.

{
  _id: 0,
  name: 'Taylor Hickle',
  email: '[email protected]',
  city: 'Milano'
}

Possiamo recuperare il documento dalla collezione, aggiornare la città e sostituirlo con la versione aggiornata.

> var user = db.users.findOne({name: 'Taylor Hickle'})

Il metodo db.collection.findOne() restituisce il primo documento che ha un campo name uguale a ‘Taylor Hickle’.

Una volta salvato il documento in una variabile, possiamo modificare un campo, aggiungerne o rimuoverne altri. Nel nostro caso cambiamo la città visto che Taylor Hickle ha deciso di spostarsi da Milano a Napoli in cui è disponibile il servizio di consegna veloce per cui non dovremo modificare altri campi.

> user.city = 'Napoli'
> user
{
  _id: 0,
  name: 'Taylor Hickle',
  email: '[email protected]',
  city: 'Napoli',
  fast_delivery: true
}

A questo punto abbiamo modificato il documento a cui punta la variabile ‘user’, ma non è stato ancora sostituito il documento presente nella collezione. Per questo useremo il metodo db.collection.replaceOne() come mostrato sotto.

ecommerce> db.users.replaceOne({name: 'Taylor Hickle'}, user)
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

db.collection.replaceOne() accetta anche un terzo argomento che consente di specificare delle opzioni aggiuntive. Una di questa è upsert che se pari al valore booleano true e se nessun documento della collezione soddisfa i criteri di selezione, aggiunge il documento passato come secondo argomento alla collezione.

> var user = {
  name: 'Anthony Kutuzov',
  email: '[email protected]',
  city: 'Pesaro'
}

> db.users.replaceOne({name: 'Anthony Kutuzov'}, user, {upsert: true})
{
  acknowledged: true,
  insertedId: ObjectId("62226b88504d7ebdaee4c838"),
  matchedCount: 0,
  modifiedCount: 0,
  upsertedCount: 1
}

In quest’ultimo caso non è presente ancora un documento con un campo ‘name’ pari a 'Anthony Kutuzov', per cui viene inserito un nuovo documento nella collezione ‘users’.

Rimuovere dei documenti con deleteOne() e deleteMany()

Per rimuovere un documento, MongoDB mette a disposizione i metodi db.collection.deleteOne() e db.collection.deleteMany().

deleteOne() rimuove il primo documento che soddisfa il gruppo di condizioni di filtro passato come primo argomento.

db.users.deleteOne({_id: 0})
{ acknowledged: true, deletedCount: 1 }

L’esempio riportato sopra rimuove il documento del database con ‘_id’ pari a 0.

deleteMany() invece rimuove tutti i documenti che soddisfano una certa condizione.

db.users.deleteMany({email: /hotmail\.com$/})
{ acknowledged: true, deletedCount: 3 }

In quest’ultimo esempio rimuoviamo dalla collezione users tutti i documenti relativi agli utenti che hanno un indirizzo di hotmail. Notiamo che in questo caso non abbiamo usato una stringa come valore del campo email, ma un’espressione regolare.

Eliminare tutti i documenti e gli indici con drop()

Per concludere questa lezione, segnaliamo il metodo db.collection.drop() che al contrario db.collection.deleteMany() rimuove l’intera collezione e tutti gli indici associati per poi ricreare nuovamente la collezione stessa.

db.users.drop()

Rispetto a db.collection.deleteMany(), è un’operazione più rapida ed efficiente.

Nella prossima lezione…

Nella prossima lezione vedremo come interrogare il database per ottenere dei documenti che soddisfano determinate condizioni. In particolare, concentremo la nostra attenzione sui metodi db.collection.findOne() e db.collection.find()

Pubblicitร