mongodb的安装与使用(二)之 增删改查与索引
0.MongoDB数据库和集合创建与删除
MongoDB 创建数据库
语法:
use DATABASE_NAME

note:查看所有数据库使用show dbs
创建的空数据库 test并不在数据库的列表中,需要向 test数据库插入一些数据才能显示它。

MongoDB 删除数据库
MongoDB 删除数据库的语法
db.dropDatabase()
只有先进入相应的数据,执行drop操作才会把test 库数据删除。

查看集合
db.getCollectionNames()

1. MongoDB插入文档
1.1 MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
案例如下:
> use test switched to db test > db.col.insert({blog: '少年阿斌的博客', ... description: '这真是有趣的博主', ... by: 'wqbin', ... url: 'https://www.cnblogs.com/wqbin/', ... tags: ['学习', '睡觉', '写代码'], ... job: "算法工程师" ... }) WriteResult({ "nInserted" : 1 }) > db.col.find() { "_id" : ObjectId("5dc02bb1e66db8e50e787f5d"), "blog" : "少年阿斌的博客", "description" : "这真是有趣的博主", "by" : "wqbin", "url" : "https://www.cnblogs.com/wqbin/",
"tags" : [ "学习", "睡觉", "写代码" ], "job" : "算法工程师" } >
col 是我们的集合名,如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。
我们也可以将数据定义为一个变量,如下所示:
> doc=({blog: '王阳的博客',
... description: '这真是爱学习的博主',
... by: 'wqbin',
... url: 'https://www.cnblogs.com/wqbin/',
... tags: ['机器学习', 'NLP', 'Fintect'],
... job: "算法工程师"
... })
-————>返回如下:
{
"blog" : "王阳的博客",
"description" : "这真是爱学习的博主",
"by" : "wqbin",
"url" : "https://www.cnblogs.com/wqbin/",
"tags" : [
"机器学习",
"NLP",
"Fintect"
],
"job" : "算法工程师"
}
>
> db.col.insert(doc)
WriteResult({ "nInserted" : 1 })
>

插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
1.2插入一条文档数据与插入多条文档数据
db.collection.insertOne():向指定集合中插入一条文档数据。
db.collection.insertMany():向指定集合中插入多条文档数据。
案例如下:
> var document = db.collection.insertOne({"title": "代码1"})
> document
{
"acknowledged" : true,
"insertedId" : ObjectId("5dc02d83e66db8e50e787f5f")
}
> db.collection.find()
{ "_id" : ObjectId("5dc02d83e66db8e50e787f5f"), "title" : "代码1" }
>
插入多条数据案例如下:
> var res = db.collection.insertMany([{"title": "代码2"}, {'title': "代码3"}])
> res
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5dc02dfae66db8e50e787f60"),
ObjectId("5dc02dfae66db8e50e787f61")
]
}
> db.collection.find()
{ "_id" : ObjectId("5dc02d83e66db8e50e787f5f"), "title" : "代码1" }
{ "_id" : ObjectId("5dc02dfae66db8e50e787f60"), "title" : "代码2" }
{ "_id" : ObjectId("5dc02dfae66db8e50e787f61"), "title" : "代码3" }
并发现可以重复插入还不报错:

2. MongoDB 删除文档
MongoDB remove()函数是用来移除集合中的数据。
MongoDB数据更新可以使用update()函数。在执行remove()函数前先执行find()命令来判断执行的条件是否正确,这是一个比较好的习惯。
remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。
remove() --过时
deleteOne()
deleteMany()
如删除集合下全部文档:
> db.col.deleteMany({}) { "acknowledged" : true, "deletedCount" : 2 } > db.col.find() >
删除 title 等于 "代码" 的全部文档
db.collection.deleteMany({ title : "代码"})
删除 title 等于 "代码" 的一个文档,如果多条则按时间删除最久的
db.col.deleteOne({"title":"代码3"})
{ "acknowledged" : true, "deletedCount" : 1 }
3.MongoDB 改动文档
3.1update命令
update命令格式:
db.collection.update(criteria,objNew,upsert,multi)
参数说明:
- criteria:查询条件
- objNew:update对象和一些更新操作符
- upsert:如果不存在update的记录,是否插入objNew这个新的文档,true为插入,默认为false,不插入。
- multi:默认是false,只更新找到的第一条记录。如果为true,把按条件查询出来的记录全部更新。
> db.classes.update({"count":{$gt:20}},{$set:{"name":"c3"}})
> db.classes.find()
{ "_id" : ObjectId("5030f3a3721e16c4ab180cd9"), "name" : "c3", "count" : 30 }
{ "_id" : ObjectId("5030f3ab721e16c4ab180cda"), "name" : "c2", "count" : 30 }
示例1:把count大于20的class name修改为c3
> db.classes.update({"count":{$gt:20}},{$set:{"name":"c4"}},false,true)
> db.classes.find()
{ "_id" : ObjectId("5030f3a3721e16c4ab180cd9"), "name" : "c4", "count" : 30 }
{ "_id" : ObjectId("5030f3ab721e16c4ab180cda"), "name" : "c4", "count" : 30 }
由于没有指定upsert和multi的值,所以全部默认为false,由结果可以看出,只修改了第一条符合条件的记录。
示例2:把count大于20的class name修改为c4,设置multi为true
> db.classes.update({"count":{$gt:20}},{$set:{"name":"c4"}},false,true)
> db.classes.find()
{ "_id" : ObjectId("5030f3a3721e16c4ab180cd9"), "name" : "c4", "count" : 30 }
{ "_id" : ObjectId("5030f3ab721e16c4ab180cda"), "name" : "c4", "count" : 30 }
由于指定了multi为true,所以对两条符合条件的记录都进行了更新。
示例3: 把count大于50的class name修改为c5,设置upsert为true
> db.classes.update({"count":{$gt:50}},{$set:{"name":"c5"}},true,false)
> db.classes.find()
{ "_id" : ObjectId("5030f3a3721e16c4ab180cd9"), "name" : "c4", "count" : 30 }
{ "_id" : ObjectId("5030f3ab721e16c4ab180cda"), "name" : "c4", "count" : 30 }
{ "_id" : ObjectId("5030f589ce8fa8884e6cd441"), "name" : "c5" }
在集合中没有count大于50的记录,但是由于指定了upsert为true,如果找不到则会插入一条新记录。
3.2 save命令
Mongodb另一个更新命令是save,格式如下:
db.collection.save(obj)
obj代表需要更新的对象,如果集合内部已经存在一个和obj相同的"_id"的记录,Mongodb会把obj对象替换集合内已存在的记录,如果不存在,则会插入obj对象。
4.数据更新操作符
4.1$inc
用法:{$inc:{field:value}}
作用:对一个数字字段的某个field增加value
示例:将name为chenzhou的学生的age增加5
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin", "age" : 22 } #查询结果显示年龄为22 > db.students.update({name:"chenzhou"},{$inc:{age:5}}) #执行修改,把age增加5 > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin", "age" : 27 } > #查询结果显示年龄为27,修改成功
4.2.$set
用法:{$set:{field:value}}
作用:把文档中某个字段field的值设为value
示例: 把wqbin的年龄设为23岁
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin", "age" : 26 } > db.students.update({name:"chenzhou"},{$set:{age:23}}) > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin", "age" : 23 } >
4.3.$unset
用法:{$unset:{field:1}}
作用:删除某个字段field
示例: 将wqbin的年龄字段删除
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin", "age" : 23 } > db.students.update({name:"wqbin"},{$unset:{age:1}}) > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin" }
4.4.$push
用法:{$push:{field:value}}
作用:把value追加到field里。注:field只能是数组类型,如果field不存在,会自动插入一个数组类型
示例:给wqbin添加别名"wangyang"
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "wqbin" } > db.students.update({name:"wqbin"},{$push:{"ailas":"wangyang"}}) > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "ailas" : [ "wangyang" ], "name" : "wqbin" } >
由结果可以看到,记录中追加了一个数组类型字段alias,且字段有一个为"wangyang"的值
4.5.pushAll
用法:{$pushAll:{field:value_array}}
作用:用法同$push一样,只是$pushAll可以一次追加多个值到一个数组字段内。
示例:给wqbin追加别名quincy,cute
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "ailas" : [ "wangyang" ], "name" : "wqbin" } > db.students.update({name:"wqbin"},{$pushAll:{"ailas":["quincy","cute"]}}) > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "ailas" : [ "wangyang", "quincy", "cute" ], "name" : "wqbin" }
4.6.$addToSet
用法:{$addToSet:{field:value}}
作用:加一个值到数组内,而且只有当这个值在数组中不存在时才增加。
示例:往wqbin的别名字段里添加两个别名
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "ailas" : [ "wangyang", "quincy", "cute" ], "name" : "wqbin" } > db.students.update({name:"wqbin"},{$addToSet:{"ailas":["coder","accountant"]}}) > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "ailas" : [ "wangyang", "quincy", "cute",["coder","accountant"]], "name" : "wqbin" }
7.$pop
用法:删除数组内第一个值:{$pop:{field:-1}}、删除数组内最后一个值:{$pop:{field:1}}
作用:用于删除数组内的一个值
示例: 删除wqbin记录中alias字段中第一个别名
9.$pullAll
用法:{$pullAll:value_array}
作用:用法同$pull一样,可以一次性删除数组内的多个值。
示例: 删除wqbin记录内的所有别名
10.$rename
用法:{$rename:{old_field_name:new_field_name}}
作用:对字段进行重命名
示例:把wqbin记录的name字段重命名为sname
5. MongoDB 查询文档
MongoDB 查询文档使用 find() 方法。
find() 方法以非结构化的方式来显示所有文档。
语法
db.collection.find(query, projection)
query:可选,使用查询操作符指定查询条件 ,默认是所有==>{}projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
MongoDB 查询数据的语法格式如下(pretty() 方法以格式化显示):

也可以指定查询范围

MongoDB 与 RDBMS Where 语句比较

6.1 MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
语法格式如下:
db.col.find({key1:value1, key2:value2}).pretty()
以下实例通过 by 和 title 键来查询 数据

6.2 MongoDB OR 条件
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
>db.col.find( { $or: [ {key1: value1}, {key2:value2} ] } ).pretty

7. MongoDB 条件操作符
条件操作符用于比较两个表达式并从MongoDB集合中获取数据。
MongoDB中条件操作符有:
$gt greater than > $gte gt equal >= $lt less than < $lte lt equal <= $ne not equal != $eq equal =
案例如下:

8. MongoDB Limit与Skip方法
Limit() 方法
MongoDB Limit() 方法
limit()方法基本语法如下所示:
db.COLLECTION_NAME.find().limit(NUMBER)
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
插入测试数据

limit(2):

注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据 limit()
Skip() 方法
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。 语法
skip() 方法脚本语法格式如下:

9. MongoDB 排序
MongoDB sort()方法
在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段
使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
语法
sort()方法基本语法如下所示:
> db.COLLECTION_NAME.find().sort({KEY:1})

这样是不行的:

注: 如果没有指定sort()方法的排序方式,默认按照文档的升序排列。其中 1 为升序排列,而-1是用于降序排列
10. MongoDB 索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
ensureIndex() 方法
MongoDB使用 ensureIndex() 方法来创建索引。
语法
ensureIndex()方法基本语法格式如下所示:
db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
nsureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
ensureIndex() 接收可选参数,可选参数列表如下:

11. MongoDB 聚合
MongoDB 聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
12.管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
- $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
- $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
- $limit:用来限制MongoDB聚合管道返回的文档数。
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
- $group:将集合中的文档分组,可用于统计结果。
- $sort:将输入文档排序后输出。
- $geoNear:输出接近某一地理位置的有序文档。

浙公网安备 33010602011771号