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

Atualizar documentos no MongoDB

1. Visão geral


O MongoDB é um banco de dados NoSQL de código aberto, multiplataforma e orientado a documentos, escrito em C++. Além disso, o MongoDB oferece alto desempenho, alta disponibilidade e dimensionamento automático.

Para atualizar os documentos no MongoDB, podemos usar métodos diferentes como updateOne , findOneAndUpdate, etc. Além disso, o MongoDB fornece vários operadores para os métodos de atualização.

Neste tutorial, discutiremos diferentes abordagens para realizar operações de atualização no MongoDB. Para cada abordagem, discutiremos primeiro a consulta do shell mongo e, em seguida, sua implementação em Java.

2. Configuração do banco de dados


Antes de passarmos para as consultas de atualização, vamos primeiro criar um banco de dados, baeldung , e uma coleção de amostras, aluno:
use baeldung;
db.createCollection(student);

Como ilustração, vamos adicionar alguns documentos à coleção aluno usando o insertMany inquerir:
db.student.insertMany([
    {
        "student_id": 8764,
        "student_name": "Paul Starc",
        "address": "Hostel 1",
        "age": 16,
        "roll_no":199406
    },
    {
        "student_id": 8765,
        "student_name": "Andrew Boult",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199408
    }
]);

Na inserção bem-sucedida, obteremos um JSON com acknowledged:true :
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("621b078485e943405d04b557"),
	ObjectId("621b078485e943405d04b558")
    ]
}

Vamos agora nos aprofundar nas diferentes maneiras de atualizar os documentos no MongoDB.

3. Usando o updateOne Método


Uma operação de atualização no MongoDB pode ser feita adicionando um novo campo, removendo um campo ou atualizando um campo existente. O updateOne  O método atualiza um único documento em uma coleção com base no filtro de consulta aplicado. Ele primeiro encontra o documento que corresponde ao filtro e, em seguida, atualiza os campos especificados.

Além disso, podemos usar diferentes operadores, como $set , $unset , $inc , etc., com o método de atualização.

Para demonstrar, vamos analisar a consulta para atualizar um único documento de uma coleção:
db.student.updateOne(
    { 
        "student_name" : "Paul Starc"
    },
    { 
        $set: {
            "address" : "Hostel 2"
        }
    }
 );

Teremos uma saída semelhante à mostrada abaixo:
{
    "acknowledged":true,
    "matchedCount":1,
    "modifiedCount":1
}

Vamos agora verificar o código do driver Java do updateOne acima inquerir:
UpdateResult updateResult = collection.updateOne(Filters.eq("student_name", "Paul Starc"),
Updates.set("address", "Hostel 2"));

Aqui, primeiro usamos o student_name campo para filtrar os documentos. Em seguida, atualizamos o endereço do documento com student_name “Paul Starc”.

4. Usando o updateMany Método


O updateMany O método atualiza todos os documentos nas coleções do MongoDB que correspondem ao filtro fornecido. Um dos benefícios de usar o updateMany é que podemos atualizar vários documentos sem perder os campos de documentos antigos.

Vamos ver a consulta do shell do MongoDB usando updateMany método:
db.student.updateMany(
    { 
        age: { 
            $lt: 20
         } 
    },
    { 
        $set:{ 
            "Review" : true 
        }
    }
);

O comando acima retornará a seguinte saída:
{
    "acknowledged":true,
    "matchedCount":2,
    "modifiedCount":2
}

Aqui, matchedCount contém o número de documentos correspondentes, enquanto modifiedCount contém o número do documento modificado.

Vamos agora examinar o código do driver Java usando o updateMany método:
UpdateResult updateResult = collection.updateMany(Filters.lt("age", 20), Updates.set("Review", true));

Aqui, todos os documentos com idade menos de 20 serão filtrados, e a Revisão campo será definido como true .

5. Usando o replaceOne Método


O replaceOne O método do MongoDB substitui todo o documento. Uma das desvantagens do replaceOne é que todos os campos mais antigos serão substituídos pelos novos campos, e os campos mais antigos também serão perdidos:
db.student.replaceOne(
    { 
        "student_id": 8764
    },
    {
        "student_id": 8764,
        "student_name": "Paul Starc",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199406
    }
);

Neste caso, teremos a seguinte saída:
{
    "acknowledged":true,
    "matchedCount":1,
    "modifiedCount":1
}

Se nenhuma correspondência for encontrada, a operação retornará o matchedCount como 0:
{
    "acknowledged":true,
    "matchedCount":0,
    "modifiedCount":0
}

Vamos escrever o código do driver Java correspondente usando o replaceOne método:
Document replaceDocument = new Document();
replaceDocument
  .append("student_id", 8764)
  .append("student_name", "Paul Starc")
  .append("address", "Hostel 2")
  .append("age",18)
  .append("roll_no", 199406);
UpdateResult updateResult = collection.replaceOne(Filters.eq("student_id", 8764), replaceDocument);

No código acima, criamos um documento pelo qual o documento mais antigo será substituído. O documento com student_id 8764 será substituído pelo documento recém-criado.

6. Usando o findOneAndReplace Método


O findOneAndReplace O método é um dos métodos avançados de atualização fornecidos pelo MongoDB e substitui o primeiro documento correspondente com base nos critérios de seleção fornecidos. Por padrão, esse método retorna o documento original. Podemos usar diferentes opções do findOneAndReplace para classificar e projetar documentos, se necessário.

Resumindo, findOneAndReplace substitui o primeiro documento correspondente da coleção com base no filtro aplicado:
db.student.findOneAndReplace(
    { 
        "student_id" : { 
            $eq : 8764 
        }
    },
    { 
        "student_id" : 8764,
        "student_name" : "Paul Starc",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199406 
    },
    {
        returnNewDocument: false
    }
);

Esta consulta retornará o seguinte documento:
{
    "student_id":8764,
    "student_name":"Paul Starc",
    "address":"Hostel 1",
    "age":16,
    "roll_no":199406
}

Se definirmos returnNewDocument para verdadeiro , a operação retornaria o documento substituído:
{
    "student_id":8764,
    "student_name":"Paul Starc",
    "address":"Hostel 2",
    "age":18,
    "roll_no":199406
}

Vamos agora usar o findOneAndReplace método para projetar o student_id e idade campos no documento retornado:
db.student.findOneAndReplace(
    { 
        "student_id" : {
        $eq : 8764 
        } 
    },
    { 
        "student_id" : 8764, 
        "student_name" : "Paul Starc",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199406 
    },
    { 
        projection: { 
            "_id" : 0,
            "student_id":1,
            "age" : 1 
        } 
    }
);

A saída da consulta acima conterá apenas os campos projetados:
{
    "student_id":"8764",
    "age":16
}

O código do driver Java da consulta acima com várias opções do findOneAndReplace:
Document replaceDocument = new Document();
replaceDocument
  .append("student_id", 8764)
  .append("student_name", "Paul Starc")
  .append("address", "Hostel 2")
  .append("age", 18)
  .append("roll_no", 199406);
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndReplace(
  Filters.eq("student_id", 8764), 
  replaceDocument,
  new FindOneAndReplaceOptions().upsert(true).sort(sort).projection(projection).returnDocument(ReturnDocument.AFTER));

Na consulta acima, o findOneAndReplace primeiro classificará os documentos em ordem crescente com base em roll_no, e o documento recém-criado substitui o documento por student_id “8764”.

7. Usando o findOneAndUpdate Método


O findOneAndUpdate O método atualiza o primeiro documento correspondente na coleção. Se mais de um documento corresponder aos critérios de seleção, ele atualizará apenas o primeiro documento correspondente. Quando atualizamos o documento, o valor de _id campo permanece inalterado:
db.student.findOneAndUpdate(
    { 
        "student_id" : 8764
    },
    { 
        $inc : { 
            "roll_no" : 5
        } 
    },
    { 
        sort: { 
            "roll_no" : 1 
        }, 
        projection: { 
            "_id" : 0,
            "student_id":1,
            "address" : 1
        }
    }
);

A saída da consulta conterá apenas o studentId e endereço do documento mais antigo:
{
    "student_id":8764,
    "address":"Hostel 1"
}

O código do driver Java da consulta acima, usando diferentes opções do findOneAndUpdate é o seguinte:
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndUpdate(
  Filters.eq("student_id", 8764),
  Updates.inc("roll_no", 5), 
  new FindOneAndUpdateOptions().sort(sort).projection(projection).returnDocument(ReturnDocument.BEFORE));

Nesse caso, o findOneAndUpdate primeiro classificará o documento em ordem crescente com base em roll_no . A consulta acima incrementa o roll_no  por 5 e, em seguida, retorna o student_id e endereço Campos.