MongoDB 基础操作之更新操作

更新

在实际操作中,可以使用更新文档的方式修改意见存在的文档。常用的更新操作有update()save()。除此之外,还可以使用updateOne()updateMany()replaceOne()

1. update()

在更新文档的操作时,可以通过特定的条件来更新一个或多个文档。

(1) 语法格式
 db.collection.update( 
      <query > ,
      <update > ,
      {
        upsert: < boolean > ,
        multi: < boolean > ,
        writeConcern: < document > ,
        collation: < document > ,
        arrayFilters: [ < filterdocument 1 > , ...]
        }
)
(2) 参数说明
  • query:欲更新文档的筛选条件
  • update:更新的字段和字段值
  • upsert:可选参数。默认为false。若设定为true,则表示在更新条件没有匹配时,会插入此文档;若设定为false,则不会新增文档。
  • multi:此为可选参数。表示当更新条件匹配时,是否会更新全部匹配问到的文档。若设置为false,则只会更新匹配到的第 1 个文档;若设置为true,则表示会更新全部匹配到的文档。该选项默认为false
  • writeConcern: 此为可选参数。表示是否使用写入策略。
  • collation:可选参数。用来指定更新的排序规则。
  • arrayFiltersMongoDB 3.6版本之后才提供的可选参数。若要更新数组中的特定的元素,则可通过此参数对条件进行筛选。
(3) 范例
  • 范例 1:将Product集合中SysNo2971文档的Weight字段的值改成1000.执行操作中需指定文档筛选条件,并且在$set: { }中设置要更新的文档内容。
    更新前文档内容:
> db.Product.find({"SysNo": 2971}).pretty()
{
    "_id" : ObjectId("60da83996350a57504489e73"),
    "SysNo" : 2971,
    "ProductName" : "DE - 1300 Earbuds",
    "Weight" : 465,  // 更新前为465
    "ProductMode" : "Set"
}

更新文档:

>db.Product.update(
     { SysNo: 2971 },  // 更新文档的条件
     { 
       "$set":  { Weight: 1000}  // 需要更新的内容
     }
)

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })


> db.Product.find({"SysNo": 2971}).pretty()

{
    "_id" : ObjectId("60da83996350a57504489e73"),
    "SysNo" : 2971,
    "ProductName" : "DE - 1300 Earbuds",
    "Weight" : 1000,  // 修改后的值
    "ProductMode" : "Set"
}
  • 范例 2:将DE -1300 Earbuds的产品颜色由Red改为Orange
    在范例文档中,产品的颜色是使用数组结构来储存的,下面将介绍更新操作的arrayFilters用法。如果想修改数组中特定的元素,则可以使用arrayFilters参数来筛选符合条件的数组元素。
    更新前的文档:
> db.Product.find({"ProductName": "DE -1300 Earbuds"}).pretty()
{
    "_id" : ObjectId("60dad284063796028af0b881"),
    "ProductName" : "DE -1300 Earbuds",
    "Color" : [
        "Red",
        "White"
    ]  // 更新前数据
}

更新文档:

> db.Product.update(
{"ProductName": "DE -1300 Earbuds"},  // 筛选条件
 {$set: {"Color.$[i]": "Orange"}},  // 修改数组中元素数据
 {arrayFilters: [{"i": {$eq: "Red"}}]}  // 筛选数组中元素的条件
)

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

在修改数组元素数据的语句中,$[i]表示数组中元素的位置。如使用$[],则表示数组中所有元素。范例中的i为自定义变量,用于arrayFilters参数对数组中的元素进行筛选。$[i]也可以直接指定元素的位置,Color.1Color数组中第2个位置的元素(元素位置从0开始计算)。
更新后的文档数据:

> db.Product.find({"ProductName": "DE -1300 Earbuds"}).pretty()
{
    "_id" : ObjectId("60dad284063796028af0b881"),
    "ProductName" : "DE -1300 Earbuds",
    "Color" : [
        "Orange",  // 更新后的数据
        "White"
    ]
}

在执行这个操作时要特别注意,一定要使用3.6版本之后的的工具(如mongod shell 3.6版本),否则在执行此操作时会报错。

2. save()

save()不仅可以插入文档,还可以更新文档。与update()不同,save()在更新文档时必须加上_id字段,从而通过_id字段对原文档进行覆盖式更新。

范例

更新前的数据

> db.Product.find({"ProductName": "DE -1300 Earbuds"}).pretty()

{
    "_id" : ObjectId("60dad284063796028af0b881"),
    "ProductName" : "DE -1300 Earbuds",
    "Color" : [
        "Orange",
        "White"
    ]
}

更新文档

> db.Product.save({
    "_id" : ObjectId("60dad284063796028af0b881"),
    "ProductName" : "DE -1300 Earbuds",
    "Color" : [
        "Orange",
        "Blue"
    ]
})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

更新后的数据

> db.Product.find({"ProductName": "DE -1300 Earbuds"}).pretty()

{
    "_id" : ObjectId("60dad284063796028af0b881"),
    "ProductName" : "DE -1300 Earbuds",
    "Color" : [
        "Orange",
        "Blue"
    ]
}
3. updateOne()

updateOne()也是一种更新文档的操作方法,但使用此方法只能更新一个文档。
更新前数据:

> db.Product.find({"SysNo": 123})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }

更新文档数据:

> db.Product.updateOne({"SysNo": 123}, {$set: {Weigth: 678997768}})

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

更新后数据:

> db.Product.find({"SysNo": 123})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 678997768, "ProductMode" : "" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }

再次操作,测试:

> db.Product.updateOne({"SysNo": 123}, {$set: {Weigth: 678997768}})

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }

> db.Product.updateOne({"SysNo": 9898998989}, {$set: {Weigth: 98676656767}}, {multi: true})

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.Product.find({"SysNo": 9898998989})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 98676656767, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e73"), "SysNo" : 9898998989, "ProductName" : "DE - 1300 Earbuds", "Weight" : 1000, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e74"), "SysNo" : 9898998989, "ProductName" : "( Role Gold) 16GB", "Weight" : 143, "ProductMode" : "Set" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : 2, "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 222, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da99fd6350a57504489e78"), "Weigth" : 88888888, "ProductMode" : "Set", "SysNo" : 9898998989 }
4. updateMany()

updateMany()方法可以同时更新多个文档,它与update()方法设定multi参数为true的用法一样。
更新前数据

> db.Product.find({"ProductMode": ""})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 678997768, "ProductMode" : "" }
{ "_id" : ObjectId("60da83996350a57504489e74"), "SysNo" : 8622, "ProductName" : "( Role Gold) 16GB", "Weight" : 143, "ProductMode" : "" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : 2, "ProductNname" : "Rarbus", "SysNo" : 333, "Weigth" : 222, "ProductMode" : "" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "" }

更新数据

> db.Product.updateMany({"ProductMode": ""}, {$set: {"ProductMode": "Set"}})

{ "acknowledged" : true, "matchedCount" : 7, "modifiedCount" : 7 }

更新后数据

> db.Product.find({"ProductMode": "Set"})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 678997768, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e73"), "SysNo" : 2971, "ProductName" : "DE - 1300 Earbuds", "Weight" : 1000, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e74"), "SysNo" : 8622, "ProductName" : "( Role Gold) 16GB", "Weight" : 143, "ProductMode" : "Set" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : 2, "ProductNname" : "Rarbus", "SysNo" : 333, "Weigth" : 222, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 123, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da99fd6350a57504489e78"), "Weigth" : 88888888, "ProductMode" : "Set" }

测试

> db.Product.updateMany({"ProductMode": "Set"}, {$set: {"SysNo": 9898998989}}, {multi: false})

{ "acknowledged" : true, "matchedCount" : 9, "modifiedCount" : 9 }

> db.Product.find({"ProductMode": "Set"})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 678997768, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e73"), "SysNo" : 9898998989, "ProductName" : "DE - 1300 Earbuds", "Weight" : 1000, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e74"), "SysNo" : 9898998989, "ProductName" : "( Role Gold) 16GB", "Weight" : 143, "ProductMode" : "Set" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : 2, "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 222, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da99fd6350a57504489e78"), "Weigth" : 88888888, "ProductMode" : "Set", "SysNo" : 9898998989 }
5. replaceOne()

replaceOne()方法与save()方法类似,都是使用覆盖的方式更新文档。不同的是,replaceOne()不需要使用使用_id字段,并且只更新匹配到的第 1 个数据。

范例
// 更新前
> db.Product.find({"SysNo": 9898998989})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 98676656767, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e73"), "SysNo" : 9898998989, "ProductName" : "DE - 1300 Earbuds", "Weight" : 1000, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da83996350a57504489e74"), "SysNo" : 9898998989, "ProductName" : "( Role Gold) 16GB", "Weight" : 143, "ProductMode" : "Set" }
{ "_id" : 1, "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da90d46350a57504489e75"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : 2, "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 222, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91676350a57504489e76"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da91866350a57504489e77"), "ProductNname" : "Rarbus", "SysNo" : 9898998989, "Weigth" : 122, "ProductMode" : "Set" }
{ "_id" : ObjectId("60da99fd6350a57504489e78"), "Weigth" : 88888888, "ProductMode" : "Set", "SysNo" : 9898998989 }

// 更新
> db.Product.replaceOne({"SysNo": 9898998989}, {Weigth: 00098676656767})

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }


// 更新后
> db.Product.find({"Weigth": 00098676656767})

{ "_id" : ObjectId("60da7be26350a57504489e72"), "Weigth" : 98676656767 }
摘抄于《MoongoDB 从入门到商业实战》
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容