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

栏目: Java · 发布时间: 5年前

内容简介:原文:本篇依然是MongoDB curd中的一篇,主要介绍document的更新,主要内容如下<!-- more -->

原文: 190218-SpringBoot高级篇 MongoDB 之修改基本使用姿势

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

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

<!-- more -->

I. 基本使用

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

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

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. 基本使用姿势

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");
}

输出结果为:

------------- 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

// 数字修改,实现添加or减少
Update numUp = new Update().inc("age", 20L);
mongoTemplate.updateFirst(query, numUp, COLLECTION_NAME);
queryAndPrint(query, "inc");

输出结果为:

------------- 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

// 数字比较修改
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 --------------

d. 乘法

乘法运算, 主要使用 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 --------------

e. 日期修改

日期修改, 如 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 --------------

2. field修改

不同于 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);
}

a. 重命名

利用 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 --------------

b. 新增成员

新增也是直接利用的 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 --------------

c. 删除成员

删除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 --------------

3. 数组操作

在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);
}

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) ;两个的区别在于前者不能插入重复数据,后者可以

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 --------------

b. 批量添加

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

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 --------------

c. 删除

借助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 --------------

d. 修改

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

  • 定位删除的数组元素方法: arrayKey.index

    arrayKey
    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 --------------

4. document操作

内嵌文档,可以所是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);
}

a. 添加

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

  • docName.fieldName

    • docName 为内嵌文档在docunent中的fieldName
    • fieldName 为内嵌文档内部需要修改的fieldName
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 --------------

c. 修改

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 --------------

d. 删除

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 --------------

II. 其他

0. 项目

1. 一灰灰Blog

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

2. 声明

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

  • 微博地址:小灰灰Blog
  • QQ: 一灰灰/3302797840

3. 扫描关注

一灰灰blog

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

知识星球

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


以上所述就是小编给大家介绍的《SpringBoot高级篇MongoDB之修改基本使用姿势》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Rust

Programming Rust

Jim Blandy / O'Reilly Media / 2016-8-25 / GBP 47.99

This practical book introduces systems programmers to Rust, the new and cutting-edge language that’s still in the experimental/lab stage. You’ll learn how Rust offers the rare and valuable combination......一起来看看 《Programming Rust》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具