04-MongoDB-更新文档

更新文档

1.更新文档

MongoDB中有三个常用的更新方法: save()/update()/findAndmodify()

2.save方法

save用于往集合里添加一个新文档或者覆盖文档

当没有指定文档_id的时候就是新增

当指定了集合中已经存在的_id的时候就是覆盖

db.collection.save(

<document>,

{

​ writeConcern: <document>

}

)

注意点: MongoDB不推荐使用db.collection.save()方法. 而是使用db.collection.insertOne()或db.collection.replaceOne() .

2.1.示例

db.person.insert([
{name:'zs', age:18},
{name:'ls', age:19},
{name:'ww', age:20},
{name:'zs', age:21},
])

db.person.save({name:'zs',age: 88})

3. update方法

db.collection.update(<filter>, <update>, <options>)

<filter>: 筛选条件

<update>: 新的内容

<options>: 额外配置

3.1 通过update覆盖满足条件数据

默认情况下如果<update>没有使用更新操作符, 那么就会使用指定的内容覆盖符合条件的内容

3.2. 示例:

// 使用update没有使用更新操作符, 那么就会使用指定的内容覆盖 
// 每执行一次覆盖一条数据 
db.person.update({name:'ww'}, {name:'zs'})

3.3. 注意点:

update方法默认情况下就是覆盖

  • 如果不想覆盖, 而是想单纯的更新, 那么就必须在第二个参数中使用'更新操作符'
db.person.update({name:'ww'},{score: 99.9},{})

update方法默认只会更新满足条件的第一个文档

  • 如果想更新所有满足条件的文档, 那么就必须指定第三个参数
db.person.update({name:'zs'}, {name:'zs', age:55}, {})

如果在使用update方法的时候, 在第二个参数中指定了_id, 那么就必须保证指定的_id和被更新的文档的_id的取值一致 否则就无法更新, 否则就会报错

// 开发技巧: 在企业开发中如果需要使用update方法, 那么就不要指定_id

db.person.update({name:'zs'}, {_id:1, name:'zs', age:55}, {})

db.person.update({name:'zs'}, {_id:ObjectId("5e9007350718cb6e37ab4515"), name:'zs', age:88}, {})

如果想更新所有满足条件的文档, 我们可以指定第三个参数的取值multi:true

// 注意点: 如果指定了multi:true, 那么就必须在第二个参数中使用'更新操作符'

db.person.update({name:'zs'},{$set: {name:'zs', age:55}}, {multi:true})

更新操作符

1.更新操作符

默认情况下update会使用新文档覆盖旧文档

如果不想覆盖而是仅仅想更新其中的某些字段

那么我们就需要使用update的更新操作符

2.$set更新操作符

$set: 更新或者新增字段, 字段存在就是更新, 字段不存在就是新增

格式: {$set:<value1>, ...}

3.示例:

db.person.update({name:'zs'}, {$set:{name:'css'}}) db.person.update({name:'ww'}, {$set:{age:'vue'}})

4.更新内嵌文档和数组

db.person.insert([
{name:'zs', age:18},
{name:'ls', age:19},
{name:'ww', age:20},
{name:'zs', age:21},
])

db.person.update({name:'ww'}, {age:55})

// 更新普通字段
db.person.update({name:'ls'}, {$set:{age:55}})
// multi: true 满足条件批量更新
db.person.update({name:'zs'}, {$set:{age:88}}, {multi:true})

db.person.insert(
{
name:'ww',
age:18,
book:{name:'React', price:2888},
tags:['html', 'JavaScript']}
)
// 更新文档字段
db.person.update({name:'ww'}, {$set:{'book.name': 'JQuery'}})

// 更新数组字段
db.person.update({name:'ww'}, {$set: {'tags.0': 'vue'}})

5.注意点:

如果操作的字段存在, 那么就是更新, 如果操作的字段不存在, 那么就是新增

db.person.update({name:'ls'}, {$set:{score: 59.5}})

如果操作的是数组字段, 如果操作索引不存在, 那么也会自动新增

如果被操作的索引前面没有数据, 那么会自动用null来填充

db.person.update({name:'ww'}, {$set: {'tags.2': 'react'}}) db.person.update({name:'ww'}, {$set: {'tags.5': 'node'}})

$unset更新操作符

1.$unset更新操作符

$unset: 删除字段

格式 :{$unset:{<field>:'', ...}}

2.示例:

// 删除普通字段
db.person.update({name:'ls'}, {$unset:{score:''}})
// 注意点: 如果使用$unset删除某一个字段, 那么后面赋值为任何的内容都不重要
db.person.update({name:'ls'}, {$unset:{age:88}})

// 删除文档字段中的字段
db.person.update({name:'ww'}, {$unset:{'book.price': ''}})
// 删除数组字段中的元素
// 注意点: 如果删除的是数组字段中的元素, 那么并不会修改数组的长度, 而是用null来填充删除的内容
db.person.update({name:'ww'}, {$unset:{'tags.1': ''}})

3.注意点:

3.1删除数组元素并不会影响数组的长度, 而是设置为Null

3.2如果删除的字段不存在, 不会做任何操作

$rename更新操作符

1.$rename更新操作符

$rename: 重命名字段

格式 :{$rename:{<field>:<newName>, ...}}

2.示例

db.person.update({name:'zs'}, {$rename:{name:'MyName'}})

// 注意点: 如果修改的是文档字段中的字段, 那么取值必须写上层级关系
db.person.update({name:'ww'}, {$rename:{'book.name':'book.BookName'}})

// 注意点: 如果要操作的字段不存在, 那么不会做任何的操作
db.person.update({name:'ls'}, {$rename:{age:'MyAge'}})

// 注意点: 如果重命名之后的名称已经存在了, 那么已经存在的字段就会被删除
// 底层的本质: 先调用了$unset删除了原有的book字段, 然后再调用$set修改字段的名称
db.person.update({name:'ww'}, {$rename:{name:'book'}})

// 注意点: 不能通过$rename更新操作符来操作数组
db.person.insert(
{
name:'ll',
age:666,
book:{name:'vue', price:999},
tags:[{name:'html', price:'123'}, {name:'js', price:456}]
}
)
// 运行报错
db.person.update({name:'ll'}, {$rename:{'tags.0.name':'tags.0.TagName'}})

3.字段转移

// 可以将外层的字段转移到内层的文档中
db.person.update({name:'ll'}, {$rename:{age:'book.age'}})
db.person.find()
// 可以将内存文档中的字段, 转移到外层文档中
db.person.update({name:'ll'}, {$rename:{'book.age':'age'}})

inc和mul更新操作符

1.inc和mul更新操作符

$inc:更新字段值(增加或者减少字段保存的值)

格式: {$inc:{<field>: <number>}}

$mul:更新字段值(乘以或者除以字段保存的值)

格式: {$mul:{<field>: <number>}}

2.示例

db.person.update({name:'zs'}, {$inc:{age:2}})
db.person.update({name:'zs'}, {$inc:{age:-5}})

db.person.update({name:'zs'}, {$mul:{age:0.5}})
db.person.update({name:'zs'}, {$mul:{age:2}})

3.注意点:

3.1只能操作数字类型字段

3.2如果操作的字段不存在, 会自动新增这个字段

不同的是inc会把操作的值赋值给新增的字段, 而mul会自动赋值为0

db.person.update({name:'ls'}, {$inc:{weight:2}}) db.person.update({name:'ls'}, {$mul:{height:2}})

min和max更新操作符

1.min和max更新操作符

$min:比较保留更小字段值

格式: {$min:{<field>: <value>}}

$max:比较保留更大字段值

格式: {$max:{<field>: <value>}}

2.示例

db.person.insert({name:'zs', age:33})
db.person.update({name:'zs'}, {$min:{age:50}})
db.person.update({name:'zs'}, {$min:{age:18}})

db.person.update({name:'zs'}, {$max:{age:5}})
db.person.update({name:'zs'}, {$max:{age:55}})

3.注意点:

如果操作的字段不存在, 那么会自动增加, 并且会将操作的值赋值给新增的字段

db.person.update({name:'ls'}, {$min:{weight:120}}) db.person.update({name:'ls'}, {$max:{height:175}})

inc/mul不同, min/max不仅仅能操作数值类型的字段, 只要是可以比较的字段都可以操作

db.person.insert({name:'def', age:666}) db.person.update({name:'def'}, {$min:{name:'efg'}}) db.person.update({name:'def'}, {$min:{name:'cde'}}) 
// 注意点: 不是相同的数据类型也可以进行比较 
db.person.update({name:'ls'}, {$min:{age:null}})

4. 排序规则

MongoDB对BSON的数据类型有一个潜在的排序规则

Null

Numbers(ints, longs, doubles, decimals)

Symbol, String

Object

Array

BinData

ObjectId

Boolean

Date

Timestamp

Regular Expression

数组更新操作符

1.$addToSet数组更新操作符

$addToSet: 向数组字段中添加元素

格式 : {$addToSet: {<field>:<values>, ...}}

2.示例

db.person.insert([
{name:'zs', books:[{name:'html', price:66}, {name:'js', price:88}], tags:['html', 'js']},
{name:'ls', books:[{name:'vue', price:99}, {name:'node', price:199}], tags:['vue', 'node']}
])
db.person.update({name:'zs'}, {$addToSet:{tags:'react'}})

3.注意点

注意点: 如果操作的元素不存在, 那么会自动新增, 并且将操作的值赋值给新增的数组字段

db.person.update({name:'zs'}, {$addToSet:{other:'123'}})

$addToSet会自动去重, 如果添加的元素已经存在了, 那么就不会添加了

db.person.update({name:'zs'}, {$addToSet:{other:'123'}})

注意点: 如果往数组字段中添加的是文档类型, 那么必须一模一样才会去重

db.person.update({name:'zs'}, {$addToSet:{books:{name:'html', price:66}}})
db.person.update({name:'zs'}, {$addToSet:{books:{price:66, name:'html'}}})

注意点: 如果往数组字段中添加的是数组, 那么也必须一模一样才会去重

db.person.update({name:'ls'}, {$addToSet:{tags:['1', '2']}}) db.person.update({name:'ls'}, {$addToSet:{tags:['1', '2']}}) db.person.update({name:'ls'}, {$addToSet:{tags:['2', '1']}})

注意点: 如果往往数组字段中添加的是数组, 那么默认情况下会将整个数组作为一个元素添加进去

// 如果不想诶一个整体添加进去,那么必须使用$each来添加

db.person.update({name:'ls'}, {$addToSet:{tags:{$each: ['1', '2', '3']}}})

$push数组更新操作符

$push: 向数组字段中添加元素(不去重)

格式 : {$push: {<field>:<value1>, ...}}

$pop数组更新操作符

$pop: 从数组字段中删除元素

格式: {$pop: {<field>:<1|-1>, ...}}

**$pop示例

db.person.update({name:'zs'}, {$pop:{tags:1}}) #删除最后一个 db.person.update({name:'zs'}, {$pop:{tags:-1}})#删除第一个

**$pop注意点

数组中的元素都被删除以后, 仍然会保留空的数组

$pull数组更新操作符

$pull: 从数组字段中删除特定元素

格式: {$pull: {<field>:<value|condition>, ...}}

$pull示例

db.person.insert([
{name:'zs', books:[{name:'html', price:66}, {name:'js', price:88}], tags:['html', 'js', ['1', '2']]},
{name:'ls', books:[{name:'vue', price:99}, {name:'node', price:199}], tags:['a', 'b', 'ab', 'c', 'ac']}
])
// 删除特定元素
// 根据条件删除元素
db.person.update({name:'zs'}, {$pull:{tags:'js'}})
db.person.update({name:'ls'}, {$pull:{tags:/^a/}})

3.注意点

// 注意点: 如果要删除的元素是一个数组, 那么必须一模一样才能删除

db.person.update({name:'zs'}, {$pull:{tags:['2', '1']}}) db.person.update({name:'zs'}, {$pull:{tags:['1', '2']}})

// 注意点: 如果要删除的元素是一个文档, 那么不用一模一样也可以删除

db.person.update({name:'zs'}, {$pull:{books:{price:66, name:'html'}}}) db.person.update({name:'zs'}, {$pull:{books:{name:'js'}}})

1.$pullAll数组更新操作符

$pullAll: 从数组字段中批量删除特定元素

格式: {$pullAll: {<field>: [<value1>, <value2>, ...], ...}}

2.示例

db.person.insert([
{name:'zs', books:[{name:'html', price:66}, {name:'js', price:88}], tags:['html', 'js', ['1', '2']]},
{name:'ls', books:[{name:'vue', price:99}, {name:'node', price:199}], tags:['a', 'b', 'ab', 'c', 'ac']}
])
db.person.update({name:'zs'}, {$pullAll:{tags:['html', 'js']}})

3.注意点

// 注意点: 和$pull一样, 如果删除的是数字字段中的数组元素, 那么必须一模一样才能删除

db.person.update({name:'zs'}, {$pullAll:{tags:[['2','1']]}}) db.person.update({name:'zs'}, {$pullAll:{tags:[['1','2']]}})

// 注意点: 和$pull不一样, 如果删除的是数组字段中的文档元素, 那么也必须一模一样才能删除

db.person.update({name:'zs'}, {pullAll:{books:[{price:66,name:'html'}]}}) db.person.update({name:'zs'}, {pullAll:{books:[{name:'html',price:66}]}})

1.和[]数组更新操作符

$ : 更新数组中满足条件的特定元素

格式:

db.<collection>.update(

{ <array field>:<query selector> }

{ <update operator>: {'<array field>.$':value}}

)

$[]: 更新数组中所有元素

db.<collection>.update(

{ <update operator>: {'<array field>.$[]':value}}

)

2.示例

db.person.insert([
{name:'zs', books:[{name:'html', price:66}, {name:'js', price:88}], tags:['html', 'js', ['1', '2']]},
{name:'ls', books:[{name:'vue', price:99}, {name:'node', price:199}], tags:['a', 'b', 'ab', 'c', 'ac']}
])
db.person.find()

db.person.update(
{name:'zs', tags:'js'},
{$set:{'tags.$':'JavaScript'}}
)

db.person.update(
{name:'zs'},
{$set:{'tags.$[]': 'zs'}}
)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350