MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Guia para Upsert no MongoDB

1. Visão geral


Upsert é uma combinação de inserção e atualização (inSERT + UPdate =upsert). Podemos usar o upsert com diferentes métodos de atualização, ou seja, atualizar , localizarAndModificar e replaceOne .

Aqui no MongoDB, o upsert opção é uma Booleana valor. Suponha que o valor seja true e os documentos correspondem ao filtro de consulta especificado. Nesse caso, a operação de atualização aplicada atualizará os documentos. Se o valor for true e nenhum documento corresponde à condição, esta opção insere um novo documento na coleção. O novo documento conterá os campos baseados no filtro e nas operações aplicadas.

Neste tutorial, veremos primeiro o upsert na consulta MongoDB Shell e, em seguida, use o código do driver Java.

2. Inicialização do banco de dados


Antes de avançarmos para realizar o upsert operações, primeiro precisamos configurar um novo banco de dados baeldung e uma coleção de amostras, veí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"
}]);

Em caso de inserção bem-sucedida, o comando acima imprimirá um JSON semelhante ao mostrado abaixo:
{
    "acknowledged" : true, 
    "insertedIds" : [
        ObjectId("623c1db39d55d4e137e4781b"),
	ObjectId("623c1db39d55d4e137e4781c"),
	ObjectId("623c1db39d55d4e137e4781d")
    ]
}

Adicionamos com sucesso os dados fictícios à coleção veículo .

3. Como usar a atualização Método


Nesta seção, aprenderemos a usar o upsert opção com a atualização método. O objetivo principal do upsert opção é atualizar o documento existente com base no filtro aplicado ou inserir um novo documento se o filtro não obtiver a correspondência .

Como ilustração, usaremos o $setOnInsert operador com o upsert opção para obter uma vantagem adicional na inserção de novos campos no documento.

Vamos conferir uma consulta na qual a condição do filtro corresponde ao documento existente da coleção:
db.vehicle.update(
{
    "modelName":"X5"
},
{
    "$set":{
        "companyName":"Hero Honda"
    }
},
{
    "upsert":true
});

A consulta acima retornará o seguinte documento:
{ 
    "nMatched" : 1, 
    "nUpserted" : 0,
    "nModified" : 1 
}

Aqui, veremos o código do driver Java correspondente à consulta do shell mongo acima:
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);

Na consulta acima, o campo modelName “X5” já existe na coleção, então o campo companyName desse documento será atualizado para “Hero Honda”.

Agora vamos ver um exemplo de upsert opção usando $setOnInsert operador. Será aplicável apenas no caso de adição de um novo documento:
db.vehicle.update(
{
    "modelName":"GTPR"
},
{
    "$set":{
        "companyName":"Hero Honda"
    },
    "$setOnInsert":{
        "launchYear" : 2022,
	"type" : "Bike",
	"registeredNo" : "EPS 5562"
    },  
},
{
    "upsert":true
});

A consulta acima retornará o seguinte documento:
{
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("623b378ed648af670fe50e7f")
}

O código do driver Java da consulta de atualização acima com o $setOnInsert opção 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);

Aqui, na consulta acima, a condição de filtro do campo modelName “GTPR” não corresponde a nenhum documento de coleção, então adicionaremos um novo documento à coleção. O ponto chave a ser observado é que o $setOnInsert adiciona todos os campos ao novo documento.

4. Usando o findAndModify Método


Também podemos usar o upsert opção usando a opção findAndModify método. Para este método, o valor padrão do upsert opção é false . Se definirmos o upsert opção para verdadeiro , ele executará exatamente o mesmo que o método de atualização.

Vamos verificar um caso de uso do findAndModify método com o upsert opção true :
db.vehicle.findAndModify(
{
    query:{
        "modelName":"X7"
    },
    update: {
        "$set":{
            "companyName":"Hero Honda"
        }
    },
    "upsert":true,
    "new":true
});

Nesse caso, a consulta acima retornará o documento recém-criado. Vamos verificar o código do driver Java da consulta acima:
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);

Aqui, primeiro criamos a condição de filtro e, com base nisso, atualizaremos o documento existente ou adicionaremos um novo documento à coleção veículo .

5. Usando o replaceOne Método


Vamos executar o upsert operação usando o replaceOne método. O replaceOne O método do MongoDB apenas substitui o documento único dentro da coleção se a condição corresponder.

Primeiro, vamos examinar a consulta do shell Mongo do método replace:
db.vehicle.replaceOne(
{
    "modelName":"GTPR"
},
{
    "modelName" : "GTPR",
    "companyName" : "Hero Honda",
    "launchYear" : 2022,
    "type" : "Bike",
    "registeredNo" : "EPS 5562"
},
{
    "upsert":true
});

A consulta acima retornará a seguinte resposta:
{ 
    "acknowledged" : true, 
    "matchedCount" : 1,
    "modifiedCount" : 1 
}

Agora, vamos escrever a consulta acima usando o código do 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);

Aqui, neste caso, precisamos primeiro criar um novo documento pelo qual queremos substituir o documento existente e com o upsert opção true , substituiremos o documento somente se a condição for correspondida.