本篇依然是MongoDB curd中的一篇,主要介绍document的更新,主要内容以下mysql
首先是准备好基本环境,能够参考博文git
在开始以前,先封装一个输出方法,用于打印修改后的record对象github
private void queryAndPrint(Query query, String tag) {
System.out.println("------------- after " + tag + " age -------------");
Map record = mongoTemplate.findOne(query, Map.class, COLLECTION_NAME);
System.out.println("query records: " + record);
System.out.println("------------- end " + tag + " age --------------\n");
}
复制代码
mongodb支持咱们常见的各类基本类型,而MongoTemplate也封装了很多对应的修改方法,最基础的修改,主要是借助Update
来实现spring
常见的使用姿式如:sql
public void basicUpdate() {
/* * { * "_id" : ObjectId("5c49b07ce6652f7e1add1ea2"), * "age" : 100, * "name" : "一灰灰blog", * "desc" : "Java Developer", * "add" : [ * "额外增长" * ], * "date" : ISODate("2019-01-28T08:00:08.373Z"), * "doc" : { * "key" : "小目标", * "value" : "升职加薪,迎娶白富美" * } * } */
// 1. 直接修改值的内容
Query query = new Query(Criteria.where("_id").is("5c49b07ce6652f7e1add1ea2"));
Update update = new Update().set("desc", "Java & Python Developer");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "set");
}
复制代码
输出结果为:mongodb
------------- after set age -------------
query records: {_id=5c49b07ce6652f7e1add1ea2, age=100, name=一灰灰blog, desc=Java & Python Developer, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}}
------------- end set age --------------
复制代码
数字类型修改,使用 org.springframework.data.mongodb.core.query.Update#inc
数组
// 数字修改,实现添加or减小
Update numUp = new Update().inc("age", 20L);
mongoTemplate.updateFirst(query, numUp, COLLECTION_NAME);
queryAndPrint(query, "inc");
复制代码
输出结果为:bash
------------- after inc age -------------
query records: {_id=5c49b07ce6652f7e1add1ea2, age=120, name=一灰灰blog, desc=Java & Python Developer, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}}
------------- end inc age --------------
复制代码
数字简单比较以后修改,如org.springframework.data.mongodb.core.query.Update#max
spring-boot
// 数字比较修改
Update cmpUp = new Update().max("age", 88);
mongoTemplate.updateFirst(query, cmpUp, COLLECTION_NAME);
queryAndPrint(query, "cmp");
复制代码
输出结果
------------- after cmp age -------------
query records: {_id=5c49b07ce6652f7e1add1ea2, age=120, name=一灰灰blog, desc=Java & Python Developer, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}}
------------- end cmp age --------------
复制代码
乘法运算, 主要使用 org.springframework.data.mongodb.core.query.Update#multiply
// 乘法
Update mulUp = new Update().multiply("age", 3);
mongoTemplate.updateFirst(query, mulUp, COLLECTION_NAME);
queryAndPrint(query, "multiply");
复制代码
输出结果
------------- after multiply age -------------
query records: {_id=5c49b07ce6652f7e1add1ea2, age=360.0, name=一灰灰blog, desc=Java & Python Developer, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}}
------------- end multiply age --------------
复制代码
日期修改, 如 org.springframework.data.mongodb.core.query.Update#currentDate
// 日期修改
Update dateUp = new Update().currentDate("date");
mongoTemplate.updateFirst(query, dateUp, COLLECTION_NAME);
queryAndPrint(query, "date");
复制代码
输出结果
------------- after date age -------------
query records: {_id=5c49b07ce6652f7e1add1ea2, age=360.0, name=一灰灰blog, desc=Java & Python Developer, add=[额外增长], date=Mon Feb 18 19:34:56 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}}
------------- end date age --------------
复制代码
不一样于mysql的列表是固定的,mongodb的field能够增长、删除和重命名,下面分别看下三种case如何使用
/** * 修改字段名,新增字段,删除字段 */
public void fieldUpdate() {
/** * { * "_id" : ObjectId("5c6a7ada10ffc647d301dd62"), * "age" : 28.0, * "name" : "一灰灰blog", * "desc" : "Java Developer", * "add" : [ * "额外增长" * ], * "date" : ISODate("2019-01-28T08:00:08.373Z"), * "doc" : { * "key" : "小目标", * "value" : "升职加薪,迎娶白富美" * } * } */
Query query = new Query(Criteria.where("_id").is("5c6a7ada10ffc647d301dd62"));
renameFiled(query);
addField(query);
delField(query);
}
复制代码
利用org.springframework.data.mongodb.core.query.Update#rename
来实现重命名,须要注意的是,当修改的docuemnt没有这个成员时,至关于没有任务操做
private void renameFiled(Query query) {
Update update = new Update().rename("desc", "skill");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "rename");
// 若是字段不存在,至关于没有更新
update = new Update().rename("desc", "s-skill");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "rename Not exists!");
}
复制代码
输出结果以下,后面一个语句至关于没有执行
------------- after rename age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end rename age --------------
------------- after rename Not exists! age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end rename Not exists! age --------------
复制代码
新增也是直接利用的Update#set
方法,当存在时,修改;不存在时,添加
setOnInsert
, 若是要更新的文档存在那么$setOnInsert操做符不作任何处理;private void addField(Query query) {
// 新增一个字段
// 直接使用set便可
Update update = new Update().set("new-skill", "Python");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "addField");
// 当更新一个不存在的文档时,可使用setOnInsert
// 若是要更新的文档存在那么$setOnInsert操做符不作任何处理;
}
复制代码
输出结果以下:
------------- after addField age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer, new-skill=Python}
------------- end addField age --------------
复制代码
删除document中的某个成员,借助org.springframework.data.mongodb.core.query.Update#unset
, 正好与添加对上
private void delField(Query query) {
// 删除字段,若是不存在,则不操做
Update update = new Update().unset("new-skill");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "delField");
}
复制代码
输出结果以下
------------- after delField age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end delField age --------------
复制代码
在MongoDB的document中,有两个有意思的类型,一个是数组,一个是document(便可以嵌套),这里则主要介绍下如何操做数组中的成员
/** * 更新文档中字段为数组成员的值 */
public void updateInnerArray() {
/** * { * "_id" : ObjectId("5c6a7ada10ffc647d301dd62"), * "age" : 28.0, * "name" : "一灰灰blog", * "skill" : "Java Developer", * "add" : [ * "额外增长" * ], * "date" : ISODate("2019-01-28T08:00:08.373Z"), * "doc" : { * "key" : "小目标", * "value" : "升职加薪,迎娶白富美" * } * } */
Query query = new Query(Criteria.where("_id").is("5c6a7ada10ffc647d301dd62"));
this.addData2Array(query);
this.batchAddData2Array(query);
this.delArrayData(query);
this.updateArrayData(query);
}
复制代码
在数组中新增一个数据,提供了两种方式,一个是org.springframework.data.mongodb.core.query.Update#addToSet(java.lang.String, java.lang.Object)
,一个是org.springframework.data.mongodb.core.query.Update#push(java.lang.String, java.lang.Object)
;两个的区别在于前者不能插入重复数据,后者能够
private void addData2Array(Query query) {
// 新加一个元素到数组,若是已经存在,则不会加入
String insert = "新添加>>" + System.currentTimeMillis();
Update update = new Update().addToSet("add", insert);
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "add2List");
// push 新增元素,容许出现重复的数据
update = new Update().push("add", 10);
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "push2List");
}
复制代码
输出结果
------------- after add2List age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长, 新添加>>1550489696892], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end add2List age --------------
------------- after push2List age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长, 新添加>>1550489696892, 10], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end push2List age --------------
复制代码
一次添加多个,借助addToSet
的each
来实现
private void batchAddData2Array(Query query) {
// 批量插入数据到数组中, 注意不会将重复的数据丢入mongo数组中
Update update = new Update().addToSet("add").each("2", "2", "3");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "batchAdd2List");
}
复制代码
输出结果:
------------- after batchAdd2List age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长, 新添加>>1550489696892, 10, 2, 3], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end batchAdd2List age --------------
复制代码
借助pull来精确删除某个值
private void delArrayData(Query query) {
// 删除数组中元素
Update update = new Update().pull("add", "2");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "delArrayData");
}
复制代码
输出以下,注意对比,2
没有了
------------- after delArrayData age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长, 新添加>>1550489696892, 10, 3], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end delArrayData age --------------
复制代码
修改,首先的问题是要定位,肯定删除数组中某个下标的元素,这里借助了一个有意思的站位
arrayKey.index
arrayKey
是数组在docment中的名index
表示要删除的索引一个实例以下
private void updateArrayData(Query query) {
// 使用set,field.index 来更新数组中的值
// 更新数组中的元素,若是元素存在,则直接更新;若是数组个数小于待更新的索引位置,则前面补null
Update update = new Update().set("add.1", "updateField");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "updateListData");
update = new Update().set("add.10", "nullBefore");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "updateListData");
}
复制代码
输出结果,注意后面的,若是数组个数小于待更新的索引位置,则前面补null
------------- after updateListData age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长, updateField, 10, 3], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end updateListData age --------------
------------- after updateListData age -------------
query records: {_id=5c6a7ada10ffc647d301dd62, age=28.0, name=一灰灰blog, add=[额外增长, updateField, 10, 3, null, null, null, null, null, null, nullBefore], date=Mon Jan 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end updateListData age --------------
复制代码
内嵌文档,能够所是MongoDB的一个特点了,咱们则来看下如何进行操做
/** * 更新文档中字段为document类型的值 */
public void updateInnerDoc() {
/** * { * "_id" : ObjectId("5c6a956b10ffc647d301dd63"), * "age" : 18.0, * "name" : "一灰灰blog", * "date" : ISODate("2019-02-28T08:00:08.373Z"), * "doc" : { * "key" : "小目标", * "value" : "升职加薪,迎娶白富美" * }, * "skill" : "Java Developer" * } */
Query query = new Query(Criteria.where("_id").is("5c6a956b10ffc647d301dd63"));
this.addFieldToDoc(query);
this.updateFieldOfDoc(query);
this.delFieldOfDoc(query);
}
复制代码
借助前面的站位思想,就很好实现了,定位元素的方式采用
private void addFieldToDoc(Query query) {
// 内嵌doc新增field
Update update = new Update().set("doc.title", "好好学习,每天向上!");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "addFieldToDoc");
}
复制代码
输出以下
------------- after addFieldToDoc age -------------
query records: {_id=5c6a956b10ffc647d301dd63, age=18.0, name=一灰灰blog, date=Thu Feb 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美, title=好好学习,每天向上!}, skill=Java Developer}
------------- end addFieldToDoc age --------------
复制代码
private void updateFieldOfDoc(Query query) {
// 内嵌doc修改field
Update update = new Update().set("doc.title", "新的标题:一灰灰Blog!");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "updateFieldOfDoc");
}
复制代码
输出以下
------------- after updateFieldOfDoc age -------------
query records: {_id=5c6a956b10ffc647d301dd63, age=18.0, name=一灰灰blog, date=Thu Feb 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美, title=新的标题:一灰灰Blog!}, skill=Java Developer}
------------- end updateFieldOfDoc age --------------
复制代码
private void delFieldOfDoc(Query query) {
// 删除内嵌doc中的field
Update update = new Update().unset("doc.title");
mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
queryAndPrint(query, "delFieldOfDoc");
}
复制代码
输出以下
------------- after delFieldOfDoc age -------------
query records: {_id=5c6a956b10ffc647d301dd63, age=18.0, name=一灰灰blog, date=Thu Feb 28 16:00:08 CST 2019, doc={key=小目标, value=升职加薪,迎娶白富美}, skill=Java Developer}
------------- end delFieldOfDoc age --------------
复制代码
一灰灰的我的博客,记录全部学习和工做中的博文,欢迎你们前去逛逛
尽信书则不如,以上内容,纯属一家之言,因我的能力有限,不免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
一灰灰blog
知识星球