MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Guida per Upsert in MongoDB

1. Panoramica

Upsert è una combinazione di inserimento e aggiornamento (inSERT + UPdate =upsert). Possiamo usare il upsert con diversi metodi di aggiornamento, ovvero aggiornamento , trova e modifica e replaceOne .

Qui in MongoDB, l'upsert l'opzione è un Booleano valore. Supponiamo che il valore sia vero e i documenti corrispondono al filtro di query specificato. In tal caso, l'operazione di aggiornamento applicata aggiornerà i documenti. Se il valore è vero e nessun documento soddisfa la condizione, questa opzione inserisce un nuovo documento nella raccolta. Il nuovo documento conterrà i campi in base al filtro e alle operazioni applicate.

In questo tutorial, esamineremo prima il upsert nella query MongoDB Shell e quindi utilizzare il codice del driver Java.

2. Inizializzazione database

Prima di procedere con l'upsert operazioni, prima dobbiamo impostare un nuovo database baeldung e una raccolta di campioni, veicolo :

db.vehicle.insertMany([
{
    "companyName":"Nissan", 
    "modelName":"GTR",
    "launchYear":2016,
    "type":"Sports",
    "registeredNo":"EPS 5561"
},
{ 
    "companyName":"BMW",
    "modelName":"X5",
    "launchYear":2020,
    "type":"SUV",
    "registeredNo":"LLS 6899"
},
{
    "companyName":"Honda",
    "modelName":"Gold Wing",
    "launchYear":2018,
    "type":"Bike",
    "registeredNo":"LKS 2477"
}]);

In caso di inserimento riuscito, il comando precedente stamperà un JSON simile a quello mostrato di seguito:

{
    "acknowledged" : true, 
    "insertedIds" : [
        ObjectId("623c1db39d55d4e137e4781b"),
	ObjectId("623c1db39d55d4e137e4781c"),
	ObjectId("623c1db39d55d4e137e4781d")
    ]
}

Abbiamo aggiunto con successo i dati fittizi nella raccolta veicolo .

3. Utilizzando l'aggiornamento Metodo

In questa sezione impareremo a usare il upsert opzione con l'aggiornamento metodo. Lo scopo principale del upsert l'opzione è aggiornare il documento esistente in base al filtro applicato o inserire un nuovo documento se il filtro non ottiene la corrispondenza .

A titolo illustrativo, utilizzeremo $setOnInsert operatore con il upsert opzione per ottenere un ulteriore vantaggio nell'inserimento di nuovi campi nel documento.

Esaminiamo una query in cui la condizione del filtro corrisponde al documento esistente della raccolta:

db.vehicle.update(
{
    "modelName":"X5"
},
{
    "$set":{
        "companyName":"Hero Honda"
    }
},
{
    "upsert":true
});

La query precedente restituirà il seguente documento:

{ 
    "nMatched" : 1, 
    "nUpserted" : 0,
    "nModified" : 1 
}

Qui vedremo il codice del driver Java corrispondente alla query della shell mongo sopra:

UpdateOptions options = new UpdateOptions().upsert(true);
UpdateResult updateResult = collection.updateOne(Filters.eq("modelName", "X5"), 
  Updates.combine(Updates.set("companyName", "Hero Honda")), options);
System.out.println("updateResult:- " + updateResult);

Nella query precedente, il campo modelName "X5" esiste già nella raccolta, quindi il campo companyName di quel documento verrà aggiornato a "Hero Honda".

Ora diamo un'occhiata a un esempio di upsert opzione utilizzando $setOnInsert operatore. Sarà applicabile solo in caso di aggiunta di un nuovo documento:

db.vehicle.update(
{
    "modelName":"GTPR"
},
{
    "$set":{
        "companyName":"Hero Honda"
    },
    "$setOnInsert":{
        "launchYear" : 2022,
	"type" : "Bike",
	"registeredNo" : "EPS 5562"
    },  
},
{
    "upsert":true
});

La query precedente restituirà il seguente documento:

{
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("623b378ed648af670fe50e7f")
}

Il codice del driver Java della query di aggiornamento precedente con $setOnInsert l'opzione sarà:

UpdateResult updateSetOnInsertResult = collection.updateOne(Filters.eq("modelName", "GTPR"),
  Updates.combine(Updates.set("companyName", "Hero Honda"),
  Updates.setOnInsert("launchYear", 2022),
  Updates.setOnInsert("type", "Bike"),
  Updates.setOnInsert("registeredNo", "EPS 5562")), options);
System.out.println("updateSetOnInsertResult:- " + updateSetOnInsertResult);

Qui, nella query precedente, la condizione di filtro del campo modelName "GTPR" non corrisponde ad alcun documento di raccolta, quindi aggiungeremo un nuovo documento alla raccolta. Il punto chiave da notare è che il $setOnInsert aggiunge tutti i campi nel nuovo documento.

4. Utilizzando trova e modifica Metodo

Possiamo anche usare il upsert opzione utilizzando findAndModify metodo. Per questo metodo, il valore predefinito di upsert l'opzione è falsa . Se impostiamo il upsert opzione su vero , funzionerà esattamente come il metodo di aggiornamento.

Esaminiamo un caso d'uso di findAndModify metodo con il upsert opzione vero :

db.vehicle.findAndModify(
{
    query:{
        "modelName":"X7"
    },
    update: {
        "$set":{
            "companyName":"Hero Honda"
        }
    },
    "upsert":true,
    "new":true
});

In questo caso, la query precedente restituirà il documento appena creato. Diamo un'occhiata al codice del driver Java della query precedente:

FindOneAndUpdateOptions upsertOptions = new FindOneAndUpdateOptions();
  upsertOptions.returnDocument(ReturnDocument.AFTER);
  upsertOptions.upsert(true);
Document resultDocument = collection.findOneAndUpdate(Filters.eq("modelName", "X7"),
  Updates.set("companyName", "Hero Honda"), upsertOptions);
System.out.println("resultDocument:- " + resultDocument);

Qui, abbiamo prima creato la condizione del filtro e, in base a quella, aggiorneremo il documento esistente o aggiungeremo un nuovo documento alla collezione veicolo .

5. Utilizzando replaceOne Metodo

Eseguiamo il upsert operazione utilizzando replaceOne metodo. Il replaceOne il metodo di MongoDB sostituisce semplicemente il singolo documento all'interno della raccolta se la condizione corrisponde.

Per prima cosa, esaminiamo la query della shell Mongo del metodo di sostituzione:

db.vehicle.replaceOne(
{
    "modelName":"GTPR"
},
{
    "modelName" : "GTPR",
    "companyName" : "Hero Honda",
    "launchYear" : 2022,
    "type" : "Bike",
    "registeredNo" : "EPS 5562"
},
{
    "upsert":true
});

La query precedente restituirà la seguente risposta:

{ 
    "acknowledged" : true, 
    "matchedCount" : 1,
    "modifiedCount" : 1 
}

Ora, scriviamo la query precedente usando il codice del driver Java:

Document replaceDocument = new Document();
replaceDocument.append("modelName", "GTPP")
  .append("companyName", "Hero Honda")
  .append("launchYear", 2022)
  .append("type", "Bike")
  .append("registeredNo", "EPS 5562");
UpdateResult updateReplaceResult = collection.replaceOne(Filters.eq("modelName", "GTPP"), replaceDocument, options);
System.out.println("updateReplaceResult:- " + updateReplaceResult);

Qui, in questo caso, dobbiamo prima creare un nuovo documento con il quale vogliamo sostituire il documento esistente, e con il upsert opzione vero , sostituiremo il documento solo se la condizione viene soddisfatta.