MangoDB
SQL与NoSQL区别
- 在SQL中层级关系:数据库->表->数据
- 在NoSQL中是:数据库->集合->文档
MongoDB优势
- 无数据结构限制
- 没有表结构的概念,每条记录可以有完全不同的结构
- 业务开发方便快捷
- 大数据量和高性能
- nosql数据库都具有非常高的读写性能,尤其在大数量下表现优秀
- 良好的支持
- 完善的文档
- 齐全的驱动支持
MongoDB Windows安装与运行
Windows安装MongoDB:https://www.cnblogs.com/chy18883701161/p/11100560.html
把MongoDB的bin目录加入到环境变量中
执行
1
mongod --dbpath C:\Program Files\MongoDB\Server\4.4\data # 启动
连接
- 在环境变量设置好的前提下,使用以下命令
mongo
就可以进入到mongo的操作终端了
1
mongo
- 在环境变量设置好的前提下,使用以下命令
MongoDB三元素
三元素:数据库、集合、文档
文档:就是关系型数据库中的一行。文档是一个对象,由键值对构成,是json的扩展形式
1
{"name": "abc", "gender": 1}
集合:就是关系型数据库中的表。可以存储多个文档,结构可以不固定。
{“name”: “abc”, “gender”: 1} {“name”: “abc”, “age”: 18} {“title”: “abc”, “price”: 1}
MongoDB中数据库的基本使用
查看数据库
- show dbs
切换数据库
- use 数据库
查看当前的数据库
- db
删除数据库
- db.dropDatabase()
会自动创建数据库
- use 数据库
查看集合
- show tables/show collections
MongoDB中集合的基础命令
不手动创建集合,向不存在的集合中第一次加入数据时,集合会被创建出来!!!!
手动创建集合 : db.createCollection(name,options)
- name: 要创建的集合名称
- 命名规范:
- 不是空的字符
- 全部小写
- 不要有特殊符号
- 不能使用和系统自带的数据库的名称
- 最多64字节
- 命名规范:
- options: 可选参数, 指定有关内存大小及索引的选项
1 | db.createCollection('sub',{capped:true,size:10}) |
参数capped:默认值为false表示不设置上限,值为true表示设置上限
参数size:当capped值为true时,需要制定此参数。表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节,少于256字节会被定义为256
查看集合
1 | show collections |
- 删除集合:db.集合名称.drop()
1 | db.xxxx.drop() |
MongoDB数据类型
String:字符串,必须是有效的UTF-8
Boolean:存储一个布尔值,true或者false
Integer:整数可以是32位或64位,这取决于服务器
Double:存储浮点数
Arrays:数组或列表
Object:嵌入式文档
Null:存储Null值
Timestamp:时间戳, 表示从1970-1-1到现在的总秒数
Object ID是一个12字节的十六进制数
MongoDB增删改查
- mongoDB中一张表称为一个集合
MongoDB插入数据
db.集合名.insert({}) 数据格式为json,id不能重复,支持多条插入数据库
插入单条数据
1
db.sansan.insert({x:1})
插入多条数据
1
for(i=3;i<10;i++)db.sansan.insert({x:i})
MongoDB保存 修改
命令:
db.集合名称.save(document)
1
2
3db.stu.save({_id:ObjectId("5f169b37d74866264ed9a7db"), name:'gj', gender:2}) #有id 进行更改
db.stu.save({name:'gj', gender:2}) #无ID 直接增加
db.stu.find()
Mongo查询
测试数据
1
2
3
4
5
6
7db.stu.insert([{"name" : "张三", "hometown" : "长沙", "age" : 20, "gender" : true },
{"name" : "老李", "hometown" : "广州", "age" : 18, "gender" : false },
{"name" : "王麻子", "hometown" : "北京", "age" : 18, "gender" : false },
{"name" : "刘六", "hometown" : "深圳", "age" : 40, "gender" : true },
{"name" : "jerry", "hometown" : "长沙", "age" : 16, "gender" : true },
{"name" : "小永", "hometown" : "广州", "age" : 45, "gender" : true },
{"name" : "老amy", "hometown" : "衡阳", "age" : 18, "gender" : true }])查询所有数据
1
db.stu.find({条件⽂档})
pretty():将结果格式化
1
db.stu.find({条件⽂档}).pretty()
查询单条数据
1
db.stu.findOne({条件⽂档})
有条件的查询数据
1
2
3
4
5查询x等于100的数据
db.stu.find({x:100})
查询x等于100,y等于99的
db.stu.find({x:100,y:99})比较运算符
1
2
3
4
5
6
7
8等于:默认是等于判断,没有运算符
小于:$lt
小于等于:$lte
大于:$gt
大于等于:$gte
查询y大于等于18的数据
db.stu.find({y:{$gte:18}})范围运算
1
2使用$in,$nin判断是否在某个范围内查询年龄为18、28的学生
db.stu.find({age:{$in:[18,28]}})逻辑运算符
1
2or:使用$or,值为数组,数组中每个元素为json
db.stu.find({$or:[{age:{$gt:18}},{gender:false}]})自定义查询
mongo shell 是一个js的执行环境
使用$where 写一个函数, 返回满足条件的数据
1
2
3
4
5查询年龄大于30的学生
db.jerry_collection.find({
$where:function() {
return this.age>30;}
})映射:指定返回的字段,如果为1则返回改字段,如果为0则除了改字段外所有字段返回。id如果没写会默认返回
1
db.sansan.find({},{_id:1})
排序
1
2
3
4
5按照年龄升序排序
db.stu().find().sort({age:1})
按照年龄降序排序
db.stu().find().sort({age:-1})修改数据
1
db.集合名称.update({query}, {update}, {multi: boolean})
参数query:查询条件
参数update:更新操作符
参数multi:可选,默认是false,表示只更新找到的第一条数据,值为true表示把满足条件的数据全部更新
1 | db.jerry_collection.insert({x:100,y:100,z:100}) |
删除数据
1
2
3db.jerry_collection.remove({条件},{justOne:true}) mongoDB为了防止误删除,条件必须写
db.jerry_collection.remove() 删除所有数据,索引不会删除
db.jerry_collection.remove({x:100})删除表
1
db.jerry_collection.drop()
练习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99测试数据
var persons = [{
name:"jim",
age:25,
email:"75431457@qq.com",
c:89,m:96,e:87,
country:"USA",
books:["JS","C++","EXTJS","MONGODB"]
},
{
name:"tom",
age:25,
email:"214557457@qq.com",
c:75,m:66,e:97,
country:"USA",
books:["PHP","JAVA","EXTJS","C++"]
},
{
name:"lili",
age:26,
email:"344521457@qq.com",
c:75,m:63,e:97,
country:"USA",
books:["JS","JAVA","C#","MONGODB"]
},
{
name:"zhangsan",
age:27,
email:"2145567457@qq.com",
c:89,m:86,e:67,
country:"China",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lisi",
age:26,
email:"274521457@qq.com",
c:53,m:96,e:83,
country:"China",
books:["JS","C#","PHP","MONGODB"]
},
{
name:"wangwu",
age:27,
email:"65621457@qq.com",
c:45,m:65,e:99,
country:"China",
books:["JS","JAVA","C++","MONGODB"]
},
{
name:"zhaoliu",
age:27,
email:"214521457@qq.com",
c:99,m:96,e:97,
country:"China",
books:["JS","JAVA","EXTJS","PHP"]
},
{
name:"piaoyingjun",
age:26,
email:"piaoyingjun@uspcat.com",
c:39,m:54,e:53,
country:"Korea",
books:["JS","C#","EXTJS","MONGODB"]
},
{
name:"lizhenxian",
age:27,
email:"lizhenxian@uspcat.com",
c:35,m:56,e:47,
country:"Korea",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lixiaoli",
age:21,
email:"lixiaoli@uspcat.com",
c:36,m:86,e:32,
country:"Korea",
books:["JS","JAVA","PHP","MONGODB"]
},
{
name:"zhangsuying",
age:22,
email:"zhangsuying@uspcat.com",
c:45,m:63,e:77,
country:"Korea",
books:["JS","JAVA","C#","MONGODB"]
}]
for(var i = 0;i<persons.length;i++){
db.persons.insert(persons[i])
}
var persons = db.persons.find({name:"jim"})
while(persons.hasNext()){
obj = persons.next();
print(obj.books.length)
}题目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27db.stu.update({name:'张三'},{$set:{name:'zhangsan'}}) 不覆盖后面的内容
1.查询年龄大于25小于27的name,age
db.persons.find({age:{$gt:25,$lt:27}},{name:1,age:1})
2.查询出不是美国的
name db.persons.find({country:{$ne:'USA'}},{name:1})
3.查询国籍是中国或者美国的学生信息
db.persons.find({$or:[{country:'USA'},{country:'China'}]})
4.查询语文成绩大于85或者英语成绩大于90的学生信息
db.persons.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]})
5.查询出名字中存在"li"的学生信息
db.persons.find({name:/li/},{name:1})
6.查询喜欢看MONGODB和PHP的学生
db.persons.find({books:{$all:['MONGODB','PHP']}},{books:1})
7.查询第二本书是JAVA的学生信息
db.persons.find({books:'JAVA'},{books:1}) (在题目中是可以的) db.persons.find({'books.1':'JAVA'},{books:1}) (特殊情况)
8.查询喜欢的书数量是4本的学生
db.persons.find({books:{$size:4}},{books:1})
9.查询出persons中一共有多少国家分别是什么
db.persons.distinct('country')
聚合
聚合是基于数据处理的聚合管道,每个文档通过一个由多个阶段组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果
常用的管道
1 | $group:将集合中的文档分组,可用于统计结果 |
测试数据
1 | db.stu.insert({name:"a", hometown: '东北', age: 20, gender: true}) |
表达式
- 语法:表达式:’$列名’
1 | $sum: 计算总和, $sum:1 表示以⼀倍计数 |
$group
将集合中的文档分组,课用于统计结果
- _id表示分组的依据,使用某个字段的格式为 ‘$字段’
1 | db.students.aggregate( |
按照gender分组,获取不同组的平均年龄
1 | db.students.aggregate( |
$match
match是管道命令,能将结果交给后一个管道,相当于匹配条件
查询年龄大于20的学生
1 | db.students.aggregate( |
查询年龄大于20的男生,女生人数
1 | db.students.aggregate( |
Mongodb创建索引
1. 为什么mongdb需要创建索引
- 加快查询速度
- 进行数据的去重
2. mongodb创建简单的索引方法
- 语法:
db.集合名.ensureIndex({属性:1})
,1表示升序, -1表示降序
3. 创建索引前后查询速度对比
测试:插入10万条数据到数据库中
插入数据
1 | for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})} |
创建索引前
1 | db.test.find({name:'test9999'}) |
创建索引
1 | db.test.ensureIndex({name:1}) |
创建索引后
1 | db.test.find({name:'test9999'}).explain('executionStats') |
4. 索引的查看
默认情况下_id是集合的索引
查看方式:db.集合名.getIndexes()
5. 删除索引
语法:db.集合名.dropIndex({'索引名称':1})
1 | db.test.dropIndex({name:1}) |
Mongodb和Python的交互
连接数据库
1 | 方式一 |
新增数据
1 | import pymongo |
1 | from pymongo import MongoClient |
查询数据
1 | from bson.objectid import ObjectId |
修改数据
1 | 修改单条数据 |
删除数据
1 | 删除一条 |
具体练习
1 | import pymongo |