MongoDB学习笔记(三)- 文档删除、更新
文章目录
删除文档
定义
删除单个文档:db.collection.deleteOne()
删除多个文档:db.collection.deleteMany()
语法:
1db.collection.deleteOne(
2 <filter>,
3 {
4 writeConcern: <document>,
5 collation: <document>,
6 hint: <document|string> // Available starting in MongoDB 4.4
7 }
8)
9
10db.collection.deleteMany(
11 <filter>,
12 {
13 writeConcern: <document>,
14 collation: <document>
15 }
16)
参数:
参数 | 类型 | 说明 |
---|---|---|
filter | 文档 | 匹配条件。如果匹配条件给定{} ,那么删除集合中的第一个文档 |
writeConcern | 文档 | 可选。用于指定mongod对写操作的响应 |
collation | 文档 | 可选。用于指定字符串匹配规则 |
hint | 文档 | 针对单个文档删除的选项。可选。指定按条件匹配时使用的索引。如果指定了一个不存在的索引则会报错 |
返回值:
包含下列元素的文档:
acknowledged
- 如果指定了writeConcern
,值为true
;如果writeConcern
是disable的,值为false
deletedCount
- 删除的文档的个数
行为
db.collection.deleteOne()
删除符合匹配条件的第一个文档无法从大小固定的集合(capped collection)上删除文档
无法从时序集合(time series collections)中删除文档
当
db.collection.deleteOne()
作用在分片集合上时,匹配条件里必须要包含分片键值或者_id
字段如果只是删除单个文档,应该使用
deleteOne
,而不是使用deleteMany
指定
collation
的时候必须指定locale
。如果未指定collation
,则使用集合默认的collation
。collation
的格式如下:1collation: { 2 locale: <string>, 3 caseLevel: <boolean>, 4 caseFirst: <string>, 5 strength: <int>, 6 numericOrdering: <boolean>, 7 alternate: <string>, 8 maxVariable: <string>, 9 backwards: <boolean> 10}
示例
给定下面的集合:
1{ _id: 1, category: "café", status: "A" }
2{ _id: 2, category: "cafe", status: "a" }
3{ _id: 3, category: "cafE", status: "a" }
单个删除时指定collation
下面的语句将删除_id
为1的文档:
1db.myColl.deleteOne(
2 { category: "cafe", status: "A" },
3 { collation: { locale: "fr", strength: 1 } }
4)
多个删除时指定collation
下面的语句将删除所有的文档。如果collation
中通过caseLevel
指明大小写敏感,这同上就删除第一个文档
1db.myColl.deleteMany(
2 { category: "cafe", status: "A" },
3 { collation: { locale: "fr", strength: 1 } }
4)
更新文档
定义
更新单个文档: db.collection.updateOne(filter, update, options)
更新多个文档:db.collection.updateMany(filter, update, options)
语法:
1db.collection.updateOne(
2 <filter>,
3 <update>,
4 {
5 upsert: <boolean>,
6 writeConcern: <document>,
7 collation: <document>,
8 arrayFilters: [ <filterdocument1>, ... ],
9 hint: <document|string> // Available starting in MongoDB 4.2.1
10 }
11)
12
13db.collection.updateMany(
14 <filter>,
15 <update>,
16 {
17 upsert: <boolean>,
18 writeConcern: <document>,
19 collation: <document>,
20 arrayFilters: [ <filterdocument1>, ... ],
21 hint: <document|string> // Available starting in MongoDB 4.2.1
22 }
23)
参数:
参数 | 类型 | 说明 |
---|---|---|
filter | 文档 | 匹配条件。如果匹配条件给定{} ,那么更新集合中的第一个文档 |
update | 文档或者聚合管道 | 可以是带有更新操作表达式的文档,或者是聚合管道 |
upsert | 布尔值 | 可选。默认为false,即在没有匹配到文档的时候不会以新的文档插入 |
writeConcern | 文档 | 可选。用于指定mongod对写操作的响应 |
collation | 文档 | 可选。用于指定字符串匹配规则,和上面提到的删除的操作类似,也是用于扩展匹配规则 |
arrayFilters | 数组 | 可选。用于匹配要更新的文档下的数组元素,即对数组元素的条件限制 |
hint | 文档 | 针对单个文档删除的选项。可选。指定按条件匹配时使用的索引。如果指定了一个不存在的索引则会报错 |
返回值:
包含下列元素的文档:
matchedCount
- 匹配到的文档数modifiedCount
- 更新的文档数upsertedId
- 新插入的文档的_id
acknowledgeed
- 如果指定了writeConcern
,值为true
;如果writeConcern
是disable的,值为false
操作表达式
更新操作表达式由操作符和操作对象组成,具体格式如下:
1{
2 <operator1>: { <field1>: <value1>, ... },
3 <operator2>: { <field2>: <value2>, ... },
4 ...
5}
注意:更新操作符在处理操作对象的时候,不同的版本顺序不一样
- MongoDB 5.0以及之后,操作符在处理文档字段的时候,如果是字符串则按照字典顺序,如果是数字类型则按照数字顺序
- MongoDB 4.4以及之前,操作符都是按照字典顺序来处理
例如,对于下面的操作表达式:
1{ $set: { "a.2": <new value>, "a.10": <new value>, } }
- MongoDB 5.0以及之后,先处理
a.2
再处理a.10
- MongoDB 4.4以及之前,先处理
a.10
再处理a.2
字段操作符
操作符名称 | 描述 |
---|---|
$currentDate | 将字段的值设置为当前日期时间或者时间戳 |
$inc | 字段的值加上或者减去给定的值 |
$min | 对字段复制,值为给定的值和当前值较小的那个 |
$max | 对字段复制,值为给定的值和当前值较大的那个 |
$mul | 字段的值乘以给定的值 |
$rename | 对字段名称重命名 |
$set | 对字段赋值。这里是可以替换整个文档,也可以设置文档下某个字段的值 |
$setOnInsert | 如果更新的时候匹配不到现有文档而发生插入操作的时候,给对应的字段赋值 |
$unset | 从文档中删除字段 |
数组操作符
操作符名称 | 描述 |
---|---|
$ | 占位符。表示符合匹配条件的第一个数组。元素类型可能是基本类型,也可能是文档 |
$[] | 占位符。表示符合匹配条件的所有数组。即先根据条件匹配到符合条件的文档,然后对文档下面的数组所有元素进行更新 |
$[<identifier>] | 占位符,这个需要和arrayFilters 一起使用,用于更新符合特定条件的数组元素。这里的identifier 类似于变量,引用数组元素。例如:{$set: {"grades.$[elem]": 100}}, {arrayFilters: [{"elem": {$gt: 80}}]} |
$addToSet | 将元素添加到数组里。如果文档字段本身不是数组类型则会失败。另外数组里如果已经存在相同的元素则不再往里添加 |
$pop | 删除数组里的第一个或者最后一个元素。`{ $pop: { |
$pull | 将符合条件的元素从数组里删除,注意删除的时候是根据$pull 后面带的条件删除。如果作用于非数组字段那么将会出错。`{ $pull: { |
$push | 与addToSet 类似,但是$push 也会把重复元素插入到数组,默认是插入到数组末尾 |
$pusllAll | 与$pull 类似,但是pullAll 是基于给定的列表,将列表中的元素从原来数组中删除。{ $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } } |
修饰符操作符
操作符名称 | 描述 |
---|---|
$each | $each 后面跟一个数组,用于修饰$push 和$addToSet ,将后面的数组里的元素添加到匹配的数组里 |
$position | 用于修饰$push ,指定从数组 什么位置插入 |
$slice | 与$push 和 $each 一起使用,先执行插入操作,而后对结果做切片处理,比如保留后面几个元素或者前面几个元素 |
$sort | 与$push 和$each 一起使用,在执行插入的时候对元素进行排序 |
位运算操作符
作符名称 | 描述 |
---|---|
$bit | 对整型数做位运算 |
行为
- 执行update操作的用户需要有update,find和insert的权限
db.collection.updateOne
只更新匹配到的文档里的第一个- 当
Upset
设置为true
的时候且是作用在分片集合上时,匹配条件里必须要包含分片键值或者_id
字段 - 如果更新大小固定的集合(capped collection)会使得文档大小发生变化,则更新失败
- 无法从时序集合(time series collections)中更新文档
示例
Upset更新
给定下面的集合:
1{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
2{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
3{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : "0" }
执行以下命令:
1db.restaurant.updateOne(
2{"name": "Pizza Rat's Pizzaria"},
3{$set: {_id: 4, violations: 7, borough: "Manhattan"}},
4{upsert: true}
5)
由于查找对应的记录且upsert
为true
,因此会以新的记录插入
更新数组元素
给定下面的集合:
1db.students.insert([
2 { "_id" : 1, "grades" : [ 95, 92, 90 ] },
3 { "_id" : 2, "grades" : [ 98, 100, 102 ] },
4 { "_id" : 3, "grades" : [ 95, 110, 100 ] }
5])
执行下面的命令,将_id
为2的记录中值大于等于100数组元素的值设置为100。filter
筛选出了数组元素大于100的文档,而后对第一个文档指定更新操作
1db.students.updateOne(
2 { grades: { $gte: 100 } },
3 { $set: { "grades.$[element]" : 100 } },
4 { arrayFilters: [ { "element": { $gte: 100 } } ] }
5)
更新文档数组里的特定的元素
给定下面的集合:
1db.students2.insert([
2 {
3 "_id" : 1,
4 "grades" : [
5 { "grade" : 80, "mean" : 75, "std" : 6 },
6 { "grade" : 85, "mean" : 90, "std" : 4 },
7 { "grade" : 85, "mean" : 85, "std" : 6 }
8 ]
9 },
10 {
11 "_id" : 2,
12 "grades" : [
13 { "grade" : 90, "mean" : 75, "std" : 6 },
14 { "grade" : 87, "mean" : 90, "std" : 3 },
15 { "grade" : 85, "mean" : 85, "std" : 4 }
16 ]
17 }
18])
执行下面的命令,将_id
为1的文档中,文档数组里grade
大于等于85的数组元素中的mean
设置为100
删除集合和数据库
命令 - 删除集合以及和该集合关联的索引
1db.collection.drop(<options>)
命令 - 删除数据库
1db.dropDatabase(<writeConcern>)
2
3ex:
4use temp
5db.dropDatabase()