1. Overview
1.概述
MongoDB is a document-oriented NoSQL database that is publicly available. We can update the documents in a collection using various methods like update, replace and save. In order to change a specific field of the document, we’ll use different operators like $set, $inc, etc.
MongoDB是一个面向文档的NoSQL数据库,是公开可用的。我们可以使用update、replace和save等各种方法更新集合中的文档。为了改变文档的特定字段,我们将使用不同的操作符,如$set,$inc,等。
In this tutorial, we’ll learn to modify the multiple fields of a document using the update and the replace query. For demonstration purposes, we’ll first discuss the mongo shell query and then its corresponding implementation in Java.
在本教程中,我们将学习使用update和replace查询来修改一个文档的多个字段。出于演示目的,我们将首先讨论mongo shell查询,然后讨论其在Java中的相应实现。
Let’s now look into the various methods to achieve the purpose.
现在让我们来了解一下实现这一目的的各种方法。
2. Shell Query to Update Different Fields
2.更新不同字段的壳牌查询
Before we start, let us first create a new database, baeldung, and a sample collection, employee. We’ll use this collection in all the examples:
在我们开始之前,让我们首先创建一个新的数据库,baeldung,和一个样本集合,employee。我们将在所有的例子中使用这个集合。
use baeldung;
db.createCollection(employee);
Let’s now add a few documents into this collection using the insertMany query:
现在让我们使用insertMany查询向这个集合添加一些文件。
db.employee.insertMany([
{
"employee_id": 794875,
"employee_name": "David Smith",
"job": "Sales Representative",
"department_id": 2,
"salary": 20000,
"hire_date": NumberLong("1643969311817")
},
{
"employee_id": 794876,
"employee_name": "Joe Butler",
"job": "Sales Manager",
"department_id": 3,
"salary": 30000,
"hire_date": NumberLong("1645338658000")
}
]);
As a result, we’ll get a JSON with ObjectId for both the documents as shown below:
结果是,我们将得到一个带有ObjectId的JSON文件,如下图所示。
{
"acknowledged": true,
"insertedIds": [
ObjectId("6211e034b76b996845f3193d"),
ObjectId("6211e034b76b996845f3193e")
]
}
So far, we have set up the required environment. Let’s now update the documents that we just inserted.
到目前为止,我们已经设置了所需的环境。现在让我们来更新我们刚刚插入的文件。
2.1. Update Multiple Fields of a Single Document
2.1.更新单个文档的多个字段
We can use $set and $inc operators to update any field in MongoDB. The $set operator will set the newly specified value while the $inc operator will increase the value by a specified value.
我们可以使用$set和$inc操作符来更新MongoDB的任何字段。$set操作符将设置新指定的值,而$inc操作符将以指定的值增加该值。
Let’s first look into the MongoDB query to update two fields of the employee collection using the $set operator:
让我们先看看MongoDB的查询,使用$set操作符更新雇员集合的两个字段。
db.employee.updateOne(
{
"employee_id": 794875,
"employee_name": "David Smith"
},
{
$set:{
department_id:3,
job:"Sales Manager"
}
}
);
In the above query, the employee_id and employee_name field is used to filter the document and the $set operator is used to update the job and department_id fields.
在上述查询中,employee_id和employee_name字段被用来过滤文件,$set操作符被用来更新job和department_id字段。
We can also use the $set and $inc operators together in a single update query:
我们还可以在一个更新查询中同时使用$set和$inc操作符。
db.employee.updateOne(
{
"employee_id": 794875
},
{
$inc: {
department_id: 1
},
$set: {
job: "Sales Manager"
}
}
);
This will update the job field to Sales Manager and increase the department_id by 1.
这将把job字段更新为销售经理,并把department_id增加1。
2.2. Update Multiple Fields of Multiple Documents
2.2.更新多个文件的多个字段
In addition, we can also update multiple fields of more than one document in MongoDB. We simply need to include the option multi:true to modify all documents that match the filter query criteria:
此外,我们还可以更新MongoDB中一个以上文档的多个字段。我们只需要包含选项multi:true,就可以修改所有符合过滤查询条件的文档。
db.employee.update(
{
"job": "Sales Representative"
},
{
$inc: {
salary: 10000
},
$set: {
department_id: 5
}
},
{
multi: true
}
);
Alternatively, we’ll get the same results using the updateMany query:
另外,我们使用updateMany查询也会得到同样的结果。
db.employee.updateMany(
{
"job": "Sales Representative"
},
{
$inc: {
salary: 10000
},
$set: {
department_id: 5
}
}
);
In the above query, we used the updateMany method to update more than 1 document of the collection.
在上面的查询中,我们使用updateMany方法来更新集合中超过1个文档。
2.3. Common Problem While Updating Multiple Fields
2.3.更新多个字段时的常见问题
So far, we have learned to update multiple fields using the update query by providing two different operators or using a single operator on multiple fields.
到目前为止,我们已经学会了通过提供两个不同的操作符或在多个字段上使用一个操作符,使用更新查询来更新多个字段。
Now, if we use an operator multiple times with different fields in a single query, MongoDB will only update the last statement of the update query and ignore the rest:
现在,如果我们在一个查询中对不同的字段多次使用一个操作符,MongoDB将只更新更新查询的最后一条语句,而忽略其他语句。
db.employee.updateMany(
{
"employee_id": 794875
},
{
$set: {
department_id: 3
},
$set: {
job:"Sales Manager"
}
}
);
The above query will return a similar output to this:
上述查询将返回与此类似的输出。
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
In this case, the only job will be updated to “Sales Manager”. The department_id value will not be updated to 3.
在这种情况下,唯一的job将被更新为 “销售经理”。department_id值将不会被更新为3。
3. Update Fields with Java Driver
3.用Java驱动程序更新字段
So far, we have discussed the raw MongoDB queries. Let’s now perform the same operations using Java. MongoDB Java driver supports two classes to represent a MongoDB document, com.mongodb.BasicDBObject and org.bson.Document. We’ll look into both methods to update fields in a document.
到目前为止,我们已经讨论了原始 MongoDB 查询。现在我们来执行同样的操作使用Java。MongoDB Java 驱动程序支持两个类来表示 MongoDB 文档,com.mongodb.BasicDBObject 和 org.bson.Document. 我们将研究这两种方法来更新文档中的字段。
Before we proceed, let’s first connect to the employee collection inside the baeldung DB:
在我们继续之前,让我们首先连接到employee DB里面的baeldung集合。
MongoClient mongoClient = new MongoClient(new MongoClientURI("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("employee");
Here we’ve assumed that the MongoDB is running locally at the default port of 27017.
这里我们假设MongoDB在本地运行,默认端口为27017。
3.1. Using DBObject
3.1.使用DBObject
In order to create the document in MongoDB, we’ll use the com.mongodb.DBObject interface and its implementation class com.mongodb.BasicDBObject.
为了在MongoDB中创建文档,我们将使用com.mongodb.DBObject接口和其实现类com.mongodb.BasicDBObject。
The implementation of the DBObject is based on key-value pairs. The BasicDBObject is inherited from the LinkedHashMap class which is in the util package.
DBObject的实现基于键值对。BasicDBObject继承自LinkedHashMap类,它位于util包中。
Let’s now use the com.mongodb.BasicDBObject to perform the update operation on multiple fields:
现在让我们使用com.mongodb.BasicDBObject来执行对多个字段的更新操作。
BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875);
BasicDBObject updateFields = new BasicDBObject();
updateFields.append("department_id", 3);
updateFields.append("job", "Sales Manager");
BasicDBObject setQuery = new BasicDBObject();
setQuery.append("$set", updateFields);
UpdateResult updateResult = collection.updateMany(searchQuery, setQuery);
Here, first, we created a filter query on the basis of the employee_id. This operation will return a set of documents. Further, we’ve updated the value of the department_id and job according to the set query.
这里,首先,我们在employee_id的基础上创建了一个过滤查询。这个操作将返回一组文件。此外,我们根据集合查询,更新了department_id和job的值。
3.2. Using bson Document
3.2.使用bson文件
We can perform all the MongoDB operations using the bson document. For that, first, we need the collection object and then perform the update operation using the updateMany method with the filter and set functions.
我们可以使用bson文档来执行所有的MongoDB操作。为此,首先,我们需要集合对象,然后使用updateMany方法与filter和set函数执行更新操作。
UpdateResult updateQueryResult = collection.updateMany(Filters.eq("employee_id", 794875),
Updates.combine(Updates.set("department_id", 3), Updates.set("job", "Sales Manager")));
Here, we are passing a query filter to the updateMany method. The eq filter matches employee_id with the exact matching text ‘794875′. Then, we update the department_id and the job using the set operator.
在这里,我们将一个查询过滤器传递给updateMany方法。这个eq过滤器匹配employee_id和完全匹配的文本’794875’。然后,我们使用set操作符更新department_id和job。
4. Using Replace Query
4.使用替换查询
The naive approach to update the multiple fields of a document is to replace it with a new document that has updated values.
更新一个文件的多个字段的天真方法是用一个有更新值的新文件来替换它。
For example, if we wish to replace a document with employee_id 794875, we can execute the following query:
例如,如果我们希望用employee_id 794875替换一个文件,我们可以执行以下查询。
db.employee.replaceOne(
{
"employee_id": 794875
},
{
"employee_id": 794875,
"employee_name": "David Smith",
"job": "Sales Manager",
"department_id": 3,
"salary": 30000,
"hire_date": NumberLong("1643969311817")
}
);
The above command will print an acknowledgment JSON in the output:
上述命令将在输出中打印一个确认的JSON。
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Here, the employee_id field is used to filter the document. The second argument of the update query denotes the document from which the existing document will be replaced.
这里,employee_id字段被用来过滤文档。更新查询的第二个参数表示现有文件将被替换的文件。
In the above query, we are performing replaceOne, hence, it will replace only a single document with that filter. Alternatively, if we want to replace all the documents with that filter query, then we would need to use the updateMany method.
在上面的查询中,我们执行的是replaceOne,因此,它将只用该过滤器替换一个文档。另外,如果我们想用该过滤器查询替换所有的文档,那么我们需要使用updateMany方法。
5. Conclusion
5.总结
In this article, we explored various ways to update multiple fields of a document in MongoDB. We broadly discussed two implementations, using MongoDB shell and using Java driver.
在这篇文章中,我们探讨了在MongoDB中更新一个文档的多个字段的各种方法。我们大致讨论了两种实现方式,使用MongoDB shell和使用Java驱动。
There are various options to update the multiple fields of a document including $inc and $set operators.
有各种选项来更新一个文件的多个字段,包括$inc和$set操作符。
The implementation of all these examples and code snippets can be found over on GitHub.
所有这些例子和代码片断的实现都可以在GitHub上找到over。