前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot高级篇MongoDB之修改基本使用姿势

SpringBoot高级篇MongoDB之修改基本使用姿势

作者头像
一灰灰blog
发布2019-05-26 20:40:06
6K1
发布2019-05-26 20:40:06
举报
文章被收录于专栏:小灰灰

本篇依然是MongoDB curd中的一篇,主要介绍document的更新,主要内容如下

  • 常见类型成员的修改
  • 数组类型成员的增删改
  • document类型成员的增删改

<!-- more -->

I. 基本使用

首先是准备好基本环境,可以参考博文

在开始之前,先封装一个输出方法,用于打印修改后的record对象

代码语言:javascript
复制
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");
}

1. 基本类型修改

mongodb支持我们常见的各种基本类型,而MongoTemplate也封装了不少对应的修改方法,最基础的修改,主要是借助Update来实现

常见的使用姿势如:

a. 基本使用姿势
代码语言:javascript
复制
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");
}

输出结果为:

代码语言:javascript
复制
------------- 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 --------------
b. 数字增加/减少

数字类型修改,使用 org.springframework.data.mongodb.core.query.Update#inc

代码语言:javascript
复制
// 数字修改,实现添加or减少
Update numUp = new Update().inc("age", 20L);
mongoTemplate.updateFirst(query, numUp, COLLECTION_NAME);
queryAndPrint(query, "inc");

输出结果为:

代码语言:javascript
复制
------------- 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 --------------
c. 数字比较修改

数字简单比较之后修改,如org.springframework.data.mongodb.core.query.Update#max

代码语言:javascript
复制
// 数字比较修改
Update cmpUp = new Update().max("age", 88);
mongoTemplate.updateFirst(query, cmpUp, COLLECTION_NAME);
queryAndPrint(query, "cmp");

输出结果

代码语言:javascript
复制
------------- 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 --------------
d. 乘法

乘法运算, 主要使用 org.springframework.data.mongodb.core.query.Update#multiply

代码语言:javascript
复制
// 乘法
Update mulUp = new Update().multiply("age", 3);
mongoTemplate.updateFirst(query, mulUp, COLLECTION_NAME);
queryAndPrint(query, "multiply");

输出结果

代码语言:javascript
复制
------------- 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 --------------
e. 日期修改

日期修改, 如 org.springframework.data.mongodb.core.query.Update#currentDate

代码语言:javascript
复制
// 日期修改
Update dateUp = new Update().currentDate("date");
mongoTemplate.updateFirst(query, dateUp, COLLECTION_NAME);
queryAndPrint(query, "date");

输出结果

代码语言:javascript
复制
------------- 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 --------------

2. field修改

不同于mysql的列表是固定的,mongodb的field可以增加、删除和重命名,下面分别看下三种case如何使用

代码语言:javascript
复制
/**
 * 修改字段名,新增字段,删除字段
 */
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);
}
a. 重命名

利用org.springframework.data.mongodb.core.query.Update#rename来实现重命名,需要注意的是,当修改的docuemnt没有这个成员时,相当于没有任务操作

代码语言:javascript
复制
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!");
}

输出结果如下,后面一个语句相当于没有执行

代码语言:javascript
复制
------------- 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 --------------
b. 新增成员

新增也是直接利用的Update#set方法,当存在时,修改;不存在时,添加

  • 另外提一下setOnInsert, 如果要更新的文档存在那么$setOnInsert操作符不做任何处理;
代码语言:javascript
复制
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操作符不做任何处理;
}

输出结果如下:

代码语言:javascript
复制
------------- 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 --------------
c. 删除成员

删除document中的某个成员,借助org.springframework.data.mongodb.core.query.Update#unset, 正好与添加对上

代码语言:javascript
复制
private void delField(Query query) {
    // 删除字段,如果不存在,则不操作
    Update update = new Update().unset("new-skill");
    mongoTemplate.updateFirst(query, update, COLLECTION_NAME);

    queryAndPrint(query, "delField");
}

输出结果如下

代码语言:javascript
复制
------------- 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 --------------

3. 数组操作

在MongoDB的document中,有两个有意思的类型,一个是数组,一个是document(即可以嵌套),这里则主要介绍下如何操作数组中的成员

代码语言:javascript
复制
/**
 * 更新文档中字段为数组成员的值
 */
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);
}
a. 添加到数组中

在数组中新增一个数据,提供了两种方式,一个是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);两个的区别在于前者不能插入重复数据,后者可以

代码语言:javascript
复制
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");
}

输出结果

代码语言:javascript
复制
------------- 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 --------------
b. 批量添加

一次添加多个,借助addToSeteach来实现

代码语言:javascript
复制
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");
}

输出结果:

代码语言:javascript
复制
------------- 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 --------------
c. 删除

借助pull来精确删除某个值

代码语言:javascript
复制
private void delArrayData(Query query) {
    // 删除数组中元素
    Update update = new Update().pull("add", "2");
    mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
    queryAndPrint(query, "delArrayData");
}

输出如下,注意对比,2没有了

代码语言:javascript
复制
------------- 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 --------------
d. 修改

修改,首先的问题是要定位,确定删除数组中某个下标的元素,这里借助了一个有意思的站位

  • 定位删除的数组元素方法: arrayKey.index
    • arrayKey 是数组在docment中的名
    • index 表示要删除的索引

一个实例如下

代码语言:javascript
复制
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

代码语言:javascript
复制
------------- 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 --------------

4. document操作

内嵌文档,可以所是MongoDB的一个特色了,我们则来看下如何进行操作

代码语言:javascript
复制
/**
 * 更新文档中字段为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);
}
a. 添加

借助前面的站位思想,就很好实现了,定位元素的方式采用

  • docName.fieldName
    • docName 为内嵌文档在docunent中的fieldName
    • fieldName 为内嵌文档内部需要修改的fieldName
代码语言:javascript
复制
private void addFieldToDoc(Query query) {
    // 内嵌doc新增field
    Update update = new Update().set("doc.title", "好好学习,天天向上!");
    mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
    queryAndPrint(query, "addFieldToDoc");
}

输出如下

代码语言:javascript
复制
------------- 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 --------------
c. 修改
代码语言:javascript
复制
private void updateFieldOfDoc(Query query) {
    // 内嵌doc修改field
    Update update = new Update().set("doc.title", "新的标题:一灰灰Blog!");
    mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
    queryAndPrint(query, "updateFieldOfDoc");
}

输出如下

代码语言:javascript
复制
------------- 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 --------------
d. 删除
代码语言:javascript
复制
private void delFieldOfDoc(Query query) {
    // 删除内嵌doc中的field
    Update update = new Update().unset("doc.title");
    mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
    queryAndPrint(query, "delFieldOfDoc");
}

输出如下

代码语言:javascript
复制
------------- 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 --------------

II. 其他

0. 项目

1. 一灰灰Blog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

3. 扫描关注

一灰灰blog

QrCode
QrCode

知识星球

goals
goals
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • I. 基本使用
    • 1. 基本类型修改
      • a. 基本使用姿势
      • b. 数字增加/减少
      • c. 数字比较修改
      • d. 乘法
      • e. 日期修改
    • 2. field修改
      • a. 重命名
      • b. 新增成员
      • c. 删除成员
    • 3. 数组操作
      • a. 添加到数组中
      • b. 批量添加
      • c. 删除
      • d. 修改
    • 4. document操作
      • a. 添加
      • c. 修改
      • d. 删除
  • II. 其他
    • 0. 项目
      • 1. 一灰灰Blog
        • 2. 声明
          • 3. 扫描关注
          相关产品与服务
          云数据库 MongoDB
          腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档