sql >> Base de Datos >  >> NoSQL >> MongoDB

Guía de Upsert en MongoDB

1. Resumen

Upsert es una combinación de inserción y actualización (inSERT + UPdate =upsert). Podemos usar el upsert con diferentes métodos de actualización, es decir, actualizar , buscar y modificar y reemplazar uno .

Aquí en MongoDB, el upsert la opción es un booleano valor. Supongamos que el valor es verdadero y los documentos coinciden con el filtro de consulta especificado. En ese caso, la operación de actualización aplicada actualizará los documentos. Si el valor es verdadero y ningún documento cumple la condición, esta opción inserta un nuevo documento en la colección. El nuevo documento contendrá los campos basados ​​en el filtro y las operaciones aplicadas.

En este tutorial, primero veremos el upsert en la consulta MongoDB Shell y luego use el código del controlador Java.

2. Inicialización de la base de datos

Antes de avanzar para realizar el upsert operaciones, primero necesitamos configurar una nueva base de datos baeldung y una colección de muestra, vehículo :

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"
}]);

En caso de una inserción exitosa, el comando anterior imprimirá un JSON similar al que se muestra a continuación:

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

Hemos agregado con éxito los datos ficticios a la colección vehículo .

3. Usando la actualización Método

En esta sección, aprenderemos a usar el upsert opción con la actualización método. El propósito principal del upsert La opción es actualizar el documento existente en función del filtro aplicado o insertar un documento nuevo si el filtro no coincide. .

Como ilustración, usaremos el $setOnInsert operador con upsert opción para obtener una ventaja adicional al insertar nuevos campos en el documento.

Veamos una consulta en la que la condición de filtro coincide con el documento existente de la colección:

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

La consulta anterior devolverá el siguiente documento:

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

Aquí, veremos el código del controlador Java correspondiente a la consulta de shell mongo anterior:

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);

En la consulta anterior, el campo modelName “X5” ya existe en la colección, por lo que el campo companyName de ese documento se actualizará a "Hero Honda".

Ahora veamos un ejemplo de upsert opción usando $setOnInsert operador. Será aplicable únicamente en el caso de añadir un nuevo documento:

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

La consulta anterior devolverá el siguiente documento:

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

El código del controlador Java de la consulta de actualización anterior con $setOnInsert la opción será:

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);

Aquí, en la consulta anterior, la condición de filtro del campo modelName "GTPR" no coincide con ningún documento de la colección, por lo que agregaremos un nuevo documento a la colección. El punto clave a tener en cuenta es que $setOnInsert agrega todos los campos en el nuevo documento.

4. Uso de findAndModify Método

También podemos usar el upsert opción mediante findAndModify método. Para este método, el valor predeterminado de upsert la opción es falsa . Si configuramos el upsert opción a verdadero , funcionará exactamente igual que el método de actualización.

Veamos un caso de uso de findAndModify método con upsert opción verdadero :

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

En este caso, la consulta anterior devolverá el documento recién creado. Veamos el código del controlador Java de la consulta anterior:

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);

Aquí, primero creamos la condición de filtro y, en función de eso, actualizaremos el documento existente o agregaremos un nuevo documento a la colección vehículo .

5. Uso de replaceOne Método

Realicemos el upsert operación usando replaceOne método. El reemplazar uno El método de MongoDB simplemente reemplaza el documento único dentro de la colección si la condición coincide.

Primero, echemos un vistazo a la consulta de shell de Mongo del método de reemplazo:

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

La consulta anterior devolverá la siguiente respuesta:

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

Ahora, escribamos la consulta anterior usando el código del controlador 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);

Aquí, en este caso, primero debemos crear un nuevo documento por el cual queremos reemplazar el documento existente, y con el upsert opción verdadero , reemplazaremos el documento solo si la condición se cumple.