4.mongoDB shell 之增删改操作

4.1 insert增加操作

1.向给定数据库添加集合并且添加记录

db.[documentName].insert({…})

插入数据时需注意事项:

  • 1.1 每条数据都有一个_id字段,如果不指定,则使用ObjectId类型的随机值作为id。
    ObjectId由12个字节组成,【时间戳,精确到秒–4字节】【机器标识–3字节】
    【进程id–2字节】【随机计数器–3字节】

  • 1.2 _id 字段唯一,不能重复插入

2.save操作和insert操作的区别:

  • 在遇到相同的_id情况下,save操作会对当前内容进行覆盖保存,而insert操作无法插入,报错主键重复

4.2 remove移除操作

1.删除文档中的数据

db.[documentName].remove({...})

2. 删除列表中所有的数据

db.persons.remove()

例子:删除集合person中name等于uspcat的记录

db.persons.remove({name:"uspcat"})
> db.persons.find();
{ "_id" : ObjectId("57fdebdacf77bc67373cbb8e"), "name" : "extjs4.1" }
{ "_id" : ObjectId("57fdb688cf77bc67373cbb8d"), "age" : 1, "name" : "uspcat4" }
> db.persons.remove({name:"extjs4.1"})
> db.persons.find();
{ "_id" : ObjectId("57fdb688cf77bc67373cbb8d"), "age" : 1, "name" : "uspcat4" }

小技巧
如果你想清除一个数据量十分庞大的集合,直接删除(db.persons.drop)该集合并且重新建立索引的办法比直接用remove的效率高很多

4.3 update更新操作详解

更新文档数据

db.[documentName].update({查询条件},{更新内容},<upsert>,<multi>)

(boolean)upsert: 默认为false。如果设置为true,表示如果没有找到匹配选项则创建新的文档内容进行插入
(boolean)multi: 默认情况下,只更新匹配条件下的第一个匹配文档,如果设置为true,则更新所有匹配的文档,其他字段不变
更新器没有$set的情况:将更新内容赋给查询器匹配的文档,除主键外,更新内容不包含的字段一律清除

1 强硬的文档替换式更新操作

语法:

db.[documentName].update({查询器},{修改器})

举例:

> db.text.find()
{ "_id" : ObjectId("58286ed97bd74a5a3114faca"), "name" : 
"yfc", "age" : 27 }

将name为‘yfc’的人的age改为29
> db.text.update({name:"yfc"},{age:29})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

发现字段中name不见了,只剩下age字段为29
> db.text.find()
{ "_id" : ObjectId("58286ed97bd74a5a3114faca"), "age" : 29 }

注:强硬的更新会将老文档用新文档代替,通常开发中很少使用这种方法

2 主键冲突的时候会报错并且停止更新操作

3 insertOrUpdate操作(多一个参数)
  目的:查询器查出来数据就执行更新操作,查不出来就执行插入操作
  做法db.[documentName].update({查询器},{修改器},true)

> db.text.find()
{ "_id" : ObjectId("58286ed97bd74a5a3114faca"), "age" : 29 }
{ "_id" : 1, "name" : "name1", "age" : "age1" }
{ "_id" : 2, "name" : "name2", "age" : "age2" }
{ "_id" : 3, "age" : 40 }
{ "_id" : ObjectId("58287308c60186988c96cc68"), "age" : 41 }

想要更新name=”name5”的文档,但是找不到,则进行插入操作

> db.text.update({name:"name5"},{"_id":5,age:50},true)
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 5 })
> db.text.find()    发现新增了一行
{ "_id" : ObjectId("58286ed97bd74a5a3114faca"), "age" : 29 }
{ "_id" : 1, "name" : "name1", "age" : "age1" }
{ "_id" : 2, "name" : "name2", "age" : "age2" }
{ "_id" : 3, "age" : 40 }
{ "_id" : ObjectId("58287308c60186988c96cc68"), "age" : 41 }
{ "_id" : 5, "age" : 50 }

4 批量更新操作(增加参数3,4)
  目的:对查询器查出来多个匹配结进行更新操作
  做法:db.[documentName].update({查询器},{修改器},false,true)
使用普通更新操作无法完成需求:

> db.text.find()
{ "_id" : "1", "name" : "tom1", "age" : 21 }
{ "_id" : "2", "name" : "tom2", "age" : 21 }
{ "_id" : "3", "name" : "tom3", "age" : 33 }

想要改变所有年龄为21的为22

> db.text.update({"age":21},{$set:{age:22}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

发现只是更新了第一个匹配结果

> db.text.find() 
{ "_id" : "1", "name" : "tom1", "age" : 22 }
{ "_id" : "2", "name" : "tom2", "age" : 21 }
{ "_id" : "3", "name" : "tom3", "age" : 33 }

使用批量更新操作重新试试看
增加 参数3:false(不进行insertOrUpdate操作)
   参数4:true(对所有匹配的内容进行批量修改)

> db.text.update({"age":21},{$set:{age:22}},false,true)
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })

发现所有匹配到的结果都进行了更新操作

> db.text.find() 
{ "_id" : "1", "name" : "tom1", "age" : 22 }
{ "_id" : "2", "name" : "tom2", "age" : 22 }
{ "_id" : "3", "name" : "tom3", "age" : 33 }

5.使用修改器来完成局部更新的操作

修改器名称 语法 案例
$set {$set:{field:value}} {$set:{ gender: "male"}}

指定一个键值对,如果存在该键就进行修改,如果不存在则进行添加
update之前

> db.text.find() 
{ "_id" : "1", "name" : "tom1", "age" : 22 }
{ "_id" : "2", "name" : "tom2", "age" : 22 }
{ "_id" : "3", "name" : "tom3", "age" : 33 }

将姓名为 tom3 的人的性别 gender 改为 male :
update之后,发现多了一个gender键

> db.text.update({"name":"tom3"},{$set:{gender:"male"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.text.find()
{ "_id" : "1", "name" : "tom1", "age" : 22 }
{ "_id" : "2", "name" : "tom2", "age" : 22 }
{ "_id" : "3", "name" : "tom3", "age" : 33, "gender" : "male" }
修改器名称 语法 案例
$inc {$inc:{field:value}} {$inc:{"age":1}}

操作对象必须是数字类型,可以为指定的键对应的数字类型的数值进行加减操作(正数为加,负数为减)

> db.user.find()
{ "_id" : 1, "name" : "user1", "age" : 21 }
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }

给user1年龄加3
> db.user.update({"name":"user1"},{$inc:{"age":3}}) 
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

发现user1的年龄增加了3岁
> db.user.find() 
{ "_id" : 1, "name" : "user1", "age" : 24 }
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
修改器名称 语法 案例
$unset {$unset:{field:1}} {$unset:{}}

移除指定的键:

移除age键

> db.user.update({"name":"user1"},{$unset:{"age":1}}) 
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

发现user1的age键不见了
> db.user.find() 
{ "_id" : 1, "name" : "user1" }
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
修改器名称 语法 案例
$push {$push:{field:value}} {$push:{books:"JS"}}

(该修改器只针对数组有效
1.如果指定的键是数组则追加新的数值
2.如果不存在指定的键则创建数组类型的键值对

> db.user.update({"name":"user1"},{$push:{"age":1}})
> db.user.update({"name":"user1"},{$push:{"age":2}})
> db.user.update({"name":"user1"},{$push:{"age":1}})


 看到增加了数组类型的age键值对
> db.user.find() 
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1 ] }
修改器名称 语法 案例
$pushAll {$pushAll:{field:array}}} {$pushAll:{books:["JS","java"]}}

批量对数组添加数据,如果不存在则创建
(该修改器只针对数组有效

> db.user.update({"name":"user1"},{$pushAll:{"books":["java","python","scala"]}})
> db.user.find()
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1, 3, 4, 5, 4 ], "books" : [ "java", "python", "scala" ] }
修改器名称 语法 案例
$addToSet {$addToSet:{field:value}} {$pushAll:{books:"JS"}}

对数组添加数据,对于存在的数据不加入,如果不存在则加入
(该修改器只针对数组有效

原始数据:
> db.user.find()
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1, 3, 4, 5, 4 ], "books" : [ "java", "python", "scala" ] }


> db.user.update({"name":"user1"},{$addToSet:{"books":"java"}})
没有写成功,因为java已经存在于数组中了

> db.user.update({"name":"user1"},{$addToSet:{"books":"javaWeb"}})

写成功了,java因为存在所以不写入,javaWeb因为不存在所以写入了:
> db.user.find()
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1, 3, 4, 5, 4 ], "books" : [ "java", "python", "scala", "javaWeb" ] }
修改器名称 语法 案例
$pop {$pop:{field:value}}} {$pop:{books:1}}

从指定数组删除首/尾的值。-1:删除首部值 1:删除尾部值
(该修改器只针对数组有效

原始数据:
> db.user.find()
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1, 3, 4, 5, 4 ], "books" : [ "java", "python", "scala", "javaWeb" ] }

删除 user1 的 books 数组中第一个元素
> db.user.update({"name":"user1"},{$pop:{"books":-1}}) 

发现 book 数组中的 java 不见了
> db.user.find()  
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1, 3, 4, 5, 4 ], "books" : [ "python", "scala", "javaWeb" ] }
修改器名称 语法 案例
$pull {$pull:{field:value}} {$pull:{"age":1}}

删除数组中指定的数值
(该修改器只针对数组有效

原始数据:
> db.user.find()
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 1, 2, 1, 3, 4 ], "books" : [ "python", "scala", "javaWeb" ], "gender" : "male" }

删除age数组中所有的1
> db.user.update({"name":"user1"},{$pull:{"age":1}},false,true) 

发现age数组中已经没有了1
> db.user.find() 
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 2, 3, 4 ], "books" : [ "python", "scala", "javaWeb" ], "gender" : "male" }
修改器名称 语法 案例
$pullAll {$pullAll:{field:value}} {$pullAll:{books:"javaWeb"}}

一次性删除多个指定的数值
(该修改器只针对数组有效

{ "_id" : 1, "name" : "user1", "age" : [ 2, 3, 4 ], "books" : [ "python", "scala", "javaWeb" ], "gender" : "male" }

批量删除 user1 的 books属性中的"python","javaWeb"
> db.user.update({"name":"user1"},{$pullAll:{"books":["python","javaWeb"]}})

"python","javaWeb"已经被删掉了
> db.user.find()
{ "_id" : 2, "name" : "user2", "age" : 22 }
{ "_id" : 3, "name" : "user3", "age" : 23 }
{ "_id" : 1, "name" : "user1", "age" : [ 2, 3, 4 ], "books" : [ "scala" ], "gender" : "male"}

其他类型

1.数组定位器

如果数组有多个值我们只想对其中一部分进行操作,就要用到定位器

例子:
例如有文档

{"_id":"4",
"desc":
[{"name":"js","type":"avi"},
{"name":"hadoop","type":"rmvb"},
{"name":"spark","type":"mp4"}]}

我们要向desc数组中type等于”avi”的文档增加一个相同的作者author是”llj”

注:切记修改器是放到最外面,后面要学的查询器是放到内层的

2.$add$each 结合完成批量数组更新

对文档:{ “_id” : 1, “books” : [ “js”, “scala” ] }中的内容进行修改
向books数组插入”js”、”python”两个值,要求做重复性检查

> db.user.update({"_id":1},{$addToSet:{books:{$each:["js","python"]}}})

发现update执行后,只对”python”进行了更新,而”js”没有插入

> db.user.find()  
…
{ "_id" : 1, "books" : [ "js", "scala", "python" ] }

3.存在分配与查询效率

当document被创建的时候DB为其分配内存和预留内存,当修改操作不超过预留内存的时候,则速度非常快,反之,超过了预留内存则会消耗时间

4.runCommand函数和findAndModify函数

runCommand可以执行mongoDB中的特殊函数
findAndModify就是特殊函数之一,它的作用是返回update或remove后的文档
格式:

runCommand({"findAndModify":"文档名称",
            query:{查询器},
            sort{排序},
            new:true,
            update:{更新器},
            remove:true
}).value

举例:
更新文档{ "_id" : 3, "name" : "user3", "age" : 23 },将其中的age改为88

> ps = db.runCommand({
findAndModify:"user",
query:{_id:3},
update:{$set:{age:88}},
new:true
})
> ps.value
{ "_id" : 3, "name" : "user3", "age" : 88 }

你可能感兴趣的:(4.mongoDB shell 之增删改操作)