原文链接:http://www.mkyong.com/mongodb/spring-data-mongodb-update-document/
In Spring data – MongoDB, you can use following methods to update documents.
- save – Update the whole object, if “_id” is present, perform an update, else insert it.
- updateFirst – Updates the first document that matches the query.
- updateMulti – Updates all documents that match the query.
- Upserting – If no document that matches the query, a new document is created by combining the query and update object.
- findAndModify – Same with updateMulti, but it has an extra option to return either the old or newly updated document.
P.S All examples are tested under mongo-java-driver-2.11.0.jar
and spring-data-mongodb-1.2.0.RELEASE.jar
1. saveOrUpdate – part 1 example
// Assume below json data is inserted into MongoDB. { "_id" : ObjectId("id"), "ic" : "1001", "name" : "appleA", "age" : 20, "createdDate" : ISODate("2013-04-06T23:17:35.530Z") } // Find the document, modify and update it with save() method. 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); //Output 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. saveOrUpdate – part 2 example
This is a failed example, read carefully, a really common mistake.
Assume below json data is inserted into MongoDB.
{
"_id" : ObjectId("id"),
"ic" : "1002",
"name" : "appleB",
"age" : 20,
"createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}
In Query
, you get the document returned with a single “name” field value only, it did happened often to save the object returned size. The returned “User” object has null value in the fields : age, ic and createdDate, if you modify the ‘age’ field and update it, it will override everything instead of update the modified field – ‘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);
Output
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]
After the save(), the field ‘age’ is updated correctly, but ic and createdDate are both set to null, the entire “user” object is updated. To update a single field / key value, don’t use save(), use updateFirst() or updateMulti() instead.
3. updateFirst example
Updates the first document that matches the query. In this case, only the single field “age” is updated.
{
"_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);
Output
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 example
Updates all documents that matches the query.
{
"_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);
}
Output
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 example
If document is matched, update it, else create a new document by combining the query and update object, it’s works like 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);
Output, a new document is created by combining both query and update object.
serTest5 - User [id=id, ic=null, name=appleZ, age=21, createdDate=null]
6. findAndModify example
Find and modify and get the newly updated object from a single operation.
{
"_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);
Output
userTest6 - User [id=id, ic=1111, name=appleF, age=101, createdDate=Sun Apr 07 13:11:34 MYT 2013]
7. Full example
Full application to combine everything from example 1 to 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());
uses.add(user1);
uses.add(user2);
uses.add(user3);
uses.add(user4);
uses.add(user5);
uses.add(user6);
monoOperation.insert(users, User.class);
// ase 1 ... find and update
Sysem.out.println("Case 1");
Quey query1 = new Query();
quey1.addCriteria(Criteria.where("name").is("appleA"));
Use userTest1 = mongoOperation.findOne(query1, User.class);
Sysem.out.println("userTest1 - " + userTest1);
useTest1.setAge(99);
monoOperation.save(userTest1);
Use userTest1_1 = mongoOperation.findOne(query1, User.class);
Sysem.out.println("userTest1_1 - " + userTest1_1);
// ase 2 ... select single field only
Sysem.out.println("\nCase 2");
Quey query2 = new Query();
quey2.addCriteria(Criteria.where("name").is("appleB"));
quey2.fields().include("name");
Use userTest2 = mongoOperation.findOne(query2, User.class);
Sysem.out.println("userTest2 - " + userTest2);
useTest2.setAge(99);
monoOperation.save(userTest2);
// oppss, you just override everything, it caused ic=null an
// reatedDate=null
Quey query2_1 = new Query();
quey2_1.addCriteria(Criteria.where("name").is("appleB"));
Use userTest2_1 = mongoOperation.findOne(query2_1, User.class);
Sysem.out.println("userTest2_1 - " + userTest2_1);
Sysem.out.println("\nCase 3");
Quey query3 = new Query();
quey3.addCriteria(Criteria.where("name").is("appleC"));
quey3.fields().include("name");
Use userTest3 = mongoOperation.findOne(query3, User.class);
Sysem.out.println("userTest3 - " + userTest3);
Updte update3 = new Update();
updte3.set("age", 100);
monoOperation.updateFirst(query3, update3, User.class);
Quey query3_1 = new Query();
quey3_1.addCriteria(Criteria.where("name").is("appleC"));
Use userTest3_1 = mongoOperation.findOne(query3_1, User.class);
Sysem.out.println("userTest3_1 - " + userTest3_1);
Sysem.out.println("\nCase 4");
Quey query4 = new Query();
quey4.addCriteria(Criteria
.where("name")
.exists(true)
.orOperator(Criteria.where("name").is("appleD"),
Criteria.where("name").is("appleE")));
Updte update4 = new Update();
updte4.set("age", 11);
updte4.unset("createdDate");
// pdate 1004 only.
// ongoOperation.updateFirst(query4, update4, User.class);
// pdate all matched
monoOperation.updateMulti(query4, update4, User.class);
Sysem.out.println(query4.toString());
Lis<User> usersTest4 = mongoOperation.find(query4, User.class);
for(User userTest4 : usersTest4) {
System.out.println("userTest4 - " + userTest4);
}
Sysem.out.println("\nCase 5");
Quey query5 = new Query();
quey5.addCriteria(Criteria.where("name").is("appleZ"));
Updte update5 = new Update();
updte5.set("age", 21);
monoOperation.upsert(query5, update5, User.class);
Use userTest5 = mongoOperation.findOne(query5, User.class);
Sysem.out.println("userTest5 - " + userTest5);
Sysem.out.println("\nCase 6");
Quey query6 = new Query();
quey6.addCriteria(Criteria.where("name").is("appleF"));
Updte update6 = new Update();
updte6.set("age", 101);
updte6.set("ic", 1111);
Use userTest6 = mongoOperation.findAndModify(query6, update6,
new FindAndModifyOptions().returnNew(true), User.class);
Sysem.out.println("userTest6 - " + userTest6);
monoOperation.dropCollection(User.class);
}
}
Output
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]
相关推荐
Spring Data MongoDB API。 Spring Data MongoDB 开发文档。
Spring Data MongoDB中文文档 便宜下载了。
Spring集成MongoDB官方指定jar包:spring-data-mongodb-1.4.1.RELEASE.jar
Spring Data MongoDB 2.1中的新特性 5.2。Spring Data MongoDB 2.0中的新特性 5.3。Spring Data MongoDB 1.10中的新特性 5.4。Spring Data MongoDB 1.9中的新特性 5.5。Spring Data MongoDB 1.8中的新特性 5.6。...
springdata mongodb api文档、springdata mongodb api文档
Spring Data MongoDB 中文参考文档和Springboot使用例子,其中还介绍了spring-data-mongodb 如何使用mongodb的全文检索。
spring data mongodb代码参考 个人使用
6. MongoDB: A Document Store 7. Neo4j: A Graph Database 8. Redis: A Key/Value Store Part IV. Rapid Application Development 9. Persistence Layers with Spring Roo 10. REST Repository Exporter Part V. ...
Spring-data-mongodb_1.9.4_API_docs
spring-data-mongodb1.1.0.jar包
2. Spring Data Elasticsearch:展示了基本文本搜索、地理空间搜索和分面搜索的示例。使用了High Level REST Client作为模板和仓库的后端。 - example:展示了使用基本文本搜索、地理空间搜索和分面搜索的示例。 -...
spring data mongodb 聚合 管道
Spring Data MongoDB 1.1.0 API CHM版 制作成chm版,方便大家查阅
使用Spring Data MongoDB和MongoDB 3.0 17.1.1。配置选项 17.1.2。WriteConcern和WriteConcernChecking 17.1.3。认证 17.1.4。服务器端验证 17.1.5。其他事情要注意 附录 附录A:命名空间参考 元素 附录B:Poppers...
MongoDB权威指南:MongoDB:The Definitive Guide第一版 第二版 中、英文4本合集
Spring-data + MongoDb简单环境搭建源码
spring-data-mongodb-1.8.0.RELEASE(含源码)
Spring Boot MongoDB CRUD示例-Restful CRUD API 有关更多详细信息,请访问: 多练:异常处理:安全:全栈: 在一个地方同时运行后端和前端:运行Spring Boot应用程序mvn spring-boot:run