在Spring data – MongoDB中,您可以使用以下方法来更新文档。
- 保存–更新整个对象,如果存在“ _id”,则执行更新,否则将其插入。
- updateFirst –更新与查询匹配的第一个文档。
- updateMulti –更新所有与查询匹配的文档。
- Upserting –如果没有与查询匹配的文档,则通过组合查询和更新对象来创建新文档。
- findAndModify –与updateMulti相同,但是它有一个附加选项可以返回旧的或新更新的文档。
PS所有示例均在mongo-java-driver-2.11.0.jar
和spring-data-mongodb-1.2.0.RELEASE.jar
1. saveOrUpdate –第1部分示例
假设下面将json数据插入到MongoDB中。
{
"_id" : ObjectId("id"),
"ic" : "1001",
"name" : "appleA",
"age" : 20,
"createdDate" : ISODate("2013-04-06T23:17:35.530Z")
}
查找文档,使用save()
方法进行修改和更新。
Query query = new Query();
query.addCriteria(Criteria.where("name").is("appleA"));
User userTest1 = mongoOperation.findOne(query, User.class);
System.out.println("userTest1 - " + userTest1);
//modify and update with save()
userTest1.setAge(99);
mongoOperation.save(userTest1);
//get the updated object again
User userTest1_1 = mongoOperation.findOne(query, User.class);
System.out.println("userTest1_1 - " + userTest1_1);
输出量
userTest1 - User [id=id, ic=1001, name=appleA, age=20, createdDate=Sat Apr 06 23:17:35 MYT 2013]
userTest1_1 - User [id=id, ic=1001, name=appleA, age=99, createdDate=Sat Apr 06 23:17:35 MYT 2013]
注意
参见示例2,它显示了大多数开发人员的常见错误。
2. saveOrUpdate –第2部分示例
这是一个失败的示例,请仔细阅读,这是一个非常常见的错误。
假设下面将json数据插入到MongoDB中。
{
"_id" : ObjectId("id"),
"ic" : "1002",
"name" : "appleB",
"age" : 20,
"createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}
在Query
,您仅使用单个“名称”字段值返回的文档,它确实经常保存对象返回的大小。 返回的“用户”对象在age,ic和createdDate字段中具有空值,如果您修改“ age”字段并对其进行更新,它将覆盖所有内容,而不是更新修改后的字段“ age”。
Query query = new Query();
query.addCriteria(Criteria.where("name").is("appleB"));
query.fields().include("name");
User userTest2 = mongoOperation.findOne(query, User.class);
System.out.println("userTest2 - " + userTest2);
userTest2.setAge(99);
mongoOperation.save(userTest2);
// ooppss, you just override everything, it caused ic=null and
// createdDate=null
Query query1 = new Query();
query1.addCriteria(Criteria.where("name").is("appleB"));
User userTest2_1 = mongoOperation.findOne(query1, User.class);
System.out.println("userTest2_1 - " + userTest2_1);
输出量
userTest2 - User [id=51603dba3004d7fffc202391, ic=null, name=appleB, age=0, createdDate=null]
userTest2_1 - User [id=51603dba3004d7fffc202391, ic=null, name=appleB, age=99, createdDate=null]
在save()之后,正确地更新了“年龄”字段,但是ic和createdDate都设置为null,整个“用户”对象也被更新。 要更新单个字段/键值,请不要使用save(),而应使用updateFirst()或updateMulti()。
3. updateFirst示例
更新与查询匹配的第一个文档。 在这种情况下,仅更新单个字段“年龄”。
{
"_id" : ObjectId("id"),
"ic" : "1003",
"name" : "appleC",
"age" : 20,
"createdDate" : ISODate("2013-04-06T23:22:34.530Z")
}
//returns only 'name' field
Query query = new Query();
query.addCriteria(Criteria.where("name").is("appleC"));
query.fields().include("name");
User userTest3 = mongoOperation.findOne(query, User.class);
System.out.println("userTest3 - " + userTest3);
Update update = new Update();
update.set("age", 100);
mongoOperation.updateFirst(query, update, User.class);
//returns everything
Query query1 = new Query();
query1.addCriteria(Criteria.where("name").is("appleC"));
User userTest3_1 = mongoOperation.findOne(query1, User.class);
System.out.println("userTest3_1 - " + userTest3_1);
输出量
userTest3 - User [id=id, ic=null, name=appleC, age=0, createdDate=null]
userTest3_1 - User [id=id, ic=1003, name=appleC, age=100, createdDate=Sat Apr 06 23:22:34 MYT 2013]
4. updateMulti示例
更新所有与查询匹配的文档。
{
"_id" : ObjectId("id"),
"ic" : "1004",
"name" : "appleD",
"age" : 20,
"createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}
{
"_id" : ObjectId("id"),
"ic" : "1005",
"name" : "appleE",
"age" : 20,
"createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}
//show the use of $or operator
Query query = new Query();
query.addCriteria(Criteria
.where("name").exists(true)
.orOperator(Criteria.where("name").is("appleD"),
Criteria.where("name").is("appleE")));
Update update = new Update();
//update age to 11
update.set("age", 11);
//remove the createdDate field
update.unset("createdDate");
// if use updateFirst, it will update 1004 only.
// mongoOperation.updateFirst(query4, update4, User.class);
// update all matched, both 1004 and 1005
mongoOperation.updateMulti(query, update, User.class);
System.out.println(query.toString());
List<User> usersTest4 = mongoOperation.find(query4, User.class);
for (User userTest4 : usersTest4) {
System.out.println("userTest4 - " + userTest4);
}
输出量
Query: { "name" : { "$exists" : true} ,
"$or" : [ { "name" : "appleD"} , { "name" : "appleE"}]}, Fields: null, Sort: null
userTest4 - User [id=id, ic=1004, name=appleD, age=11, createdDate=null]
userTest4 - User [id=id, ic=1005, name=appleE, age=11, createdDate=null]
5. Upsert示例
如果文档匹配,则对其进行更新,否则通过组合查询和更新对象来创建新文档,其工作方式类似于findAndModifyElseCreate()
🙂
{
//no data
}
//search a document that doesn't exist
Query query = new Query();
query.addCriteria(Criteria.where("name").is("appleZ"));
Update update = new Update();
update.set("age", 21);
mongoOperation.upsert(query, update, User.class);
User userTest5 = mongoOperation.findOne(query, User.class);
System.out.println("userTest5 - " + userTest5);
输出,通过组合查询和更新对象来创建一个新文档。
userTest5 - User [id=id, ic=null, name=appleZ, age=21, createdDate=null]
6. findAndModify示例
通过单个操作查找和修改并获取新更新的对象。
{
"_id" : ObjectId("id"),
"ic" : "1006",
"name" : "appleF",
"age" : 20,
"createdDate" : ISODate("2013-04-07T13:11:34.530Z")
}
Query query6 = new Query();
query6.addCriteria(Criteria.where("name").is("appleF"));
Update update6 = new Update();
update6.set("age", 101);
update6.set("ic", 1111);
//FindAndModifyOptions().returnNew(true) = newly updated document
//FindAndModifyOptions().returnNew(false) = old document (not update yet)
User userTest6 = mongoOperation.findAndModify(
query6, update6,
new FindAndModifyOptions().returnNew(true), User.class);
System.out.println("userTest6 - " + userTest6);
输出量
userTest6 - User [id=id, ic=1111, name=appleF, age=101, createdDate=Sun Apr 07 13:11:34 MYT 2013]
7.完整的例子
完整的应用程序将示例1到6的所有内容组合在一起。
package com.mkyong.core;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import com.mkyong.config.SpringMongoConfig;
import com.mkyong.model.User;
public class UpdateApp {
public static void main(String[] args) {
// For Annotation
ApplicationContext ctx =
new AnnotationConfigApplicationContext(SpringMongoConfig.class);
MongoOperations mongoOperation =
(MongoOperations) ctx.getBean("mongoTemplate");
// insert 6 users for testing
List<User> users = new ArrayList<User>();
User user1 = new User("1001", "appleA", 20, new Date());
User user2 = new User("1002", "appleB", 20, new Date());
User user3 = new User("1003", "appleC", 20, new Date());
User user4 = new User("1004", "appleD", 20, new Date());
User user5 = new User("1005", "appleE", 20, new Date());
User user6 = new User("1006", "appleF", 20, new Date());
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
users.add(user5);
users.add(user6);
mongoOperation.insert(users, User.class);
// Case 1 ... find and update
System.out.println("Case 1");
Query query1 = new Query();
query1.addCriteria(Criteria.where("name").is("appleA"));
User userTest1 = mongoOperation.findOne(query1, User.class);
System.out.println("userTest1 - " + userTest1);
userTest1.setAge(99);
mongoOperation.save(userTest1);
User userTest1_1 = mongoOperation.findOne(query1, User.class);
System.out.println("userTest1_1 - " + userTest1_1);
// Case 2 ... select single field only
System.out.println("\nCase 2");
Query query2 = new Query();
query2.addCriteria(Criteria.where("name").is("appleB"));
query2.fields().include("name");
User userTest2 = mongoOperation.findOne(query2, User.class);
System.out.println("userTest2 - " + userTest2);
userTest2.setAge(99);
mongoOperation.save(userTest2);
// ooppss, you just override everything, it caused ic=null and
// createdDate=null
Query query2_1 = new Query();
query2_1.addCriteria(Criteria.where("name").is("appleB"));
User userTest2_1 = mongoOperation.findOne(query2_1, User.class);
System.out.println("userTest2_1 - " + userTest2_1);
System.out.println("\nCase 3");
Query query3 = new Query();
query3.addCriteria(Criteria.where("name").is("appleC"));
query3.fields().include("name");
User userTest3 = mongoOperation.findOne(query3, User.class);
System.out.println("userTest3 - " + userTest3);
Update update3 = new Update();
update3.set("age", 100);
mongoOperation.updateFirst(query3, update3, User.class);
Query query3_1 = new Query();
query3_1.addCriteria(Criteria.where("name").is("appleC"));
User userTest3_1 = mongoOperation.findOne(query3_1, User.class);
System.out.println("userTest3_1 - " + userTest3_1);
System.out.println("\nCase 4");
Query query4 = new Query();
query4.addCriteria(Criteria
.where("name")
.exists(true)
.orOperator(Criteria.where("name").is("appleD"),
Criteria.where("name").is("appleE")));
Update update4 = new Update();
update4.set("age", 11);
update4.unset("createdDate");
// update 1004 only.
// mongoOperation.updateFirst(query4, update4, User.class);
// update all matched
mongoOperation.updateMulti(query4, update4, User.class);
System.out.println(query4.toString());
List<User> usersTest4 = mongoOperation.find(query4, User.class);
for (User userTest4 : usersTest4) {
System.out.println("userTest4 - " + userTest4);
}
System.out.println("\nCase 5");
Query query5 = new Query();
query5.addCriteria(Criteria.where("name").is("appleZ"));
Update update5 = new Update();
update5.set("age", 21);
mongoOperation.upsert(query5, update5, User.class);
User userTest5 = mongoOperation.findOne(query5, User.class);
System.out.println("userTest5 - " + userTest5);
System.out.println("\nCase 6");
Query query6 = new Query();
query6.addCriteria(Criteria.where("name").is("appleF"));
Update update6 = new Update();
update6.set("age", 101);
update6.set("ic", 1111);
User userTest6 = mongoOperation.findAndModify(query6, update6,
new FindAndModifyOptions().returnNew(true), User.class);
System.out.println("userTest6 - " + userTest6);
mongoOperation.dropCollection(User.class);
}
}
输出量
Case 1
userTest1 - User [id=id, ic=1001, name=appleA, age=20, createdDate=Sun Apr 07 13:22:48 MYT 2013]
userTest1_1 - User [id=id, ic=1001, name=appleA, age=99, createdDate=Sun Apr 07 13:22:48 MYT 2013]
Case 2
userTest2 - User [id=id, ic=null, name=appleB, age=0, createdDate=null]
userTest2_1 - User [id=id, ic=null, name=appleB, age=99, createdDate=null]
Case 3
userTest3 - User [id=id, ic=null, name=appleC, age=0, createdDate=null]
userTest3_1 - User [id=id, ic=1003, name=appleC, age=100, createdDate=Sun Apr 07 13:22:48 MYT 2013]
Case 4
Query: { "name" : { "$exists" : true} , "$or" : [ { "name" : "appleD"} , { "name" : "appleE"}]}, Fields: null, Sort: null
userTest4 - User [id=id, ic=1004, name=appleD, age=11, createdDate=null]
userTest4 - User [id=id, ic=1005, name=appleE, age=11, createdDate=null]
Case 5
userTest5 - User [id=id, ic=null, name=appleZ, age=21, createdDate=null]
Case 6
userTest6 - User [id=id, ic=1006, name=appleF, age=20, createdDate=Sun Apr 07 13:22:48 MYT 2013]
下载源代码
下载它– SpringMongoDB-Update-Example.zip (29 KB)
参考文献
- MongoDB模板更新文档
- Spring Data MongoDB –保存,更新和删除文档
- Java MongoDB更新示例/
- MongoDB更新修饰符操作
- Spring Data MongoDB Hello World示例
翻译自: https://mkyong.com/mongodb/spring-data-mongodb-update-document/