您的位置:首页 > 数据库 > Mongodb

4.mongoDB shell 之增删改操作

2016-12-06 16:52 519 查看

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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: