SpringBoot高級篇MongoDB之修改基本使用姿式

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

本篇依然是MongoDB curd中的一篇,主要介紹document的更新,主要內容以下java

  • 常見類型成員的修改
  • 數組類型成員的增刪改
  • document類型成員的增刪改

<!-- more -->mysql

I. 基本使用

首先是準備好基本環境,能夠參考博文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");
}

1. 基本類型修改

mongodb支持咱們常見的各類基本類型,而MongoTemplate也封裝了很多對應的修改方法,最基礎的修改,主要是藉助Update來實現spring

常見的使用姿式如:sql

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

輸出結果爲: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 --------------

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

輸出結果爲: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 --------------

c. 數字比較修改

數字簡單比較以後修改,如org.springframework.data.mongodb.core.query.Update#maxspring-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 --------------

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 是數組在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 --------------

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或者有更好的建議,歡迎批評指正,不吝感激

3. 掃描關注

一灰灰blog

QrCode

知識星球

goals

相關文章
相關標籤/搜索