数据库 MongoDB (芒果数据库)
数据存储阶段
文件管理阶段 (.txt .doc .xls)
优势 : 数据能够长期保存
能够存储大量的数据
使用简单
缺点 : 数据一致性差
数据查找修改不方便
数据冗余度可能比较大
数据库管理阶段
优势 : 数据组织结构化下降了冗余度
提升了增删改查的效率
容易扩展
方便程序调用,作自动化处理
缺点 :须要使用sql 或者 其余特定的语句,相对比较复杂
几个概念
数据 : 可以输入到计算机中并被识别处理的信息集合
数据结构 :研究一个数据集合中数据之间关系的
数据库 : 按照数据结构,存储管理数据的仓库。数据库是在数据库 管理系统管理和控制下,在必定介质上的数据集合。
数据库管理系统 :管理数据库的软件,用于创建和维护数据库
数据库系统 : 由数据库和数据库管理系统,开发工具等组成的集合
关系型数据库
采用关系模型来组织数据结构的数据库 (二维表)
Oracle DB2 SQLServer MySql SqLite(Python标准库支持)
优势 :容易理解,相似咱们常见的表格
使用方便,都是使用sql语句,SQL语句很是成熟
数据一致性高,冗余度低,完整性好
技术成熟,可使用外部连接等比较复杂的操做
缺点 :不能很好的知足高并发需求,每次都须要进行sql语句的解析
针对含量数据的瞬间爆发读写性能不足,关系型数据库内部每步操做都须要加锁保证操做的原子性
数据扩展广泛比非关系型困难
数据一致性高,有时会浪费大量空间
非关系型数据库 (NoSql --> Not only Sql)
优势 : 高并发,大数据读写能力强
支持分布式,容易扩展
弱化了数据结构,下降了数据的一致性
缺点 : 通用性差,没有像sql那样一致的操做
操做灵活,容易混乱
没有join,有的数据库事务支持等操做
Nosql的使用状况:
1. 数据一致性要求低
2. 数据库并发处理要求高
3. 数据库设计时对大小的估算不肯定,须要分布拓展
4. 给定的数据比较容易创建起Nosql的模型
Nosql分类:
1. 键值型数据库
Redis oracle BDB Tokyo
2. 列存储数据库
HBase
3. 文档型数据库
MongoDB CouchDB
4. 图形数据库
MongoDB(非关系型 --》文档型数据库)
1. 由c++编写的数据库管理系统
2. 支持很是丰富的增删改查数据操做
3. 支持很是丰富的数据类型
4. 使用方便,便于部署,支持分布,容易拓展
5. 支持众多的编程语言接口 (python ruby c++ c# PHP)
MongoDB 安装
自动安装
sudo apt-get install mongodb
默认安装位置 /var/lib/mongodb
配置文件 /etc/mongodb.conf
命令集 /usr/bin /usr/local/bin
手动安装
1.下载MongoDB (开源)
www.mongodb.com ---》 Download ---》 community server
选择合适版本下载
2. 选择安装目录解压 (/usr/local /opt)
tar解压后获得mongo文件夹
3. 将文件夹下的命令集目录 (bin目录)添加到环境变量
PATH=$PATH:/opt/mongo....../bin
export PATH
将以上两句写在 /etc/rc.local
4.重启系统
mongodb 命令
设置数据库存储位置
mongod --dbpath 目录
设置端口号
mongod --port 8888
*若是不设置则使用默认端口号 27017
mongo
进入mongo shell界面 mongodb的交互界面用来操做数据库
退出 mongo shell : quit()
组成结构: 键值对 ---》 文档 ----》集合 ----》 数据库
----------------------------
ID | name | age
----------------------------
1 | Lily | 17
----------------------------
2 | Lucy | 18
----------------------------
{
"_id":ObjectId("abcd1234afhkasyr"),
"name":"Lily",
"age":17
},
{
"_id":ObjectId("abcd1234afasfsyr"),
"name":"Lucy",
"age":18
}
mysql 和 mongodb 概念对比
mysql mongo 含义
database database 数据库
table collection 表/集合
column field 字段/域
row document 记录/文档
index index 索引
建立数据库
use databasename
e.g.
建立一个叫 stu 的数据库
use stu
* use实际功能是表示选择使用哪一个数据库,当这个数据库不存在时即表示建立该数据库
* 使用use后数据库并不会立刻被建立,而是须要插入数据后数据库才会建立
查看数据库
show dbs
数据库名称规则
1. 原则上是任意知足如下几条的utf-8字符
2. 不能是空字符,不能含有空格' ' 点'.' '/' '\' '\0'
3. 习惯上使用英文小写
4. 长度不超过64字节
5. 不能使用 admin local config 这样的名字
admin : 存储用户
local : 存储本地数据
config : 存储分片配置信息
db : mongo系统全局变量 表明你当前正在使用的数据库
db 默认为test 若是插入数据即建立test数据库
数据库的备份和恢复
备份 mongodump -h dbhost -d dbname -o dbdir
e.g. mongodump -h 127.0.0.1 -d stu -o student
将本机下 stu 数据库备份到 当前目录的student文件夹中
会在student文件夹中自动生成一个stu文件夹则为备份文件
恢复 mongorestore -h <dbhost>:<port> -d dbname <path>
e.g. mongorestore -h 127.0.0.1:27017 -d test student/stu
将student文件夹下的备份文件stu恢复到本机的test数据库
数据库的监测命令
mongostat
insert query update delete :每秒增查改删的次数
getmore command 每秒运行命令次数
dirty used flushes 每秒操做磁盘的次数
vsize res 使用虚拟内存和物理内存
mongotop
监测每一个数据库的读写时长
ns total read write
数据集合 总时长 读时长 写时长
删除数据库
db.dropDatabase()
删除db所表明的数据库
集合的建立
db.createCollection(collection_name)
e.g. db.createCollection("class2")
在当前数据库下建立一个名字为class2的集合
查看数据库中集合
show tables
show collections
集合的命名规则:
1. 不能为空字符串,不能有'\0'
2. 不能以 system.开头 这是系统集合的保留前缀
3. 不能和保留字重复
建立集合2
当向一个集合中插入文档时,若是该集合不存在则自动建立
db.collectionName.insert()
e.g. db.class0.insert({a:1})
若是class0不存在则会建立class0集合并插入该数据
删除集合
db.collectionName.drop()
e.g. db.class0.drop()
删除class0集合
集合重命名
db.collectionName.renameCollection('new_name')
e.g. db.class2.renameCollection('class0')
将class2重命名为class0
文档
mongodb 中文档的组织形式
键值对组成文档 -----》 相似Python中的字典
bson -----》 json -----》 JavaScript
mongodb 中文档的数据组织形式为bson格式,相似Python的字典,也是由键值对构成
文档中键的命名规则 :
1. utf-8格式字符串
2. 不用有\0 习惯上不用 . 和 $
3. 以_开头的多位保留键,自定义时通常不以_开头
注意 : 文档键值对是有序的
mongodb中严格区分大小写
值 : mongodb的支持数据类型
支持的数据类型
类型 值
整型 整数
布尔类型 true false
浮点型 小数
Arrays 数组类型 [1,2,3]
Timestamp 时间戳
Date 时间日期
Object 内部文档
Null 空值
Symbol 特殊字符
String 字符串
Binary data 二进制字串
code 代码
regex 正则表达式
ObjectId ObjectId子串
ObjectId : 系统自动为每一个文档生成的不重复的主键
键名称: _id
值 : ObjectId("5b03b823e64cb5d90e9c8f5c")
24位16进制数
8 文档建立时间 6机器ID 4进程ID 6计数器
文档中键 -----》 域/字段
文档 ---------》 记录
集合中文档特色:
1. 集合中的文档域不必定相同 ---》不保证数据一致性
2. 集合中的文档结构不必定相同
集合设计原则:
1.集合中的文档尽量描述的数据相似
2.同一类文档放在相同的集合,不一样的文档分集合存放
3.层次的包裹不宜太多
插入文档
db.collectionName.insert()
e.g.
db.class0.insert({name:'Lucy',age:16,sex:'w'})
* 看成为文档插入时键能够不加引号
查看插入结果 db.class0.find()
插入多条文档
db.collectionName.insert([{},{},{}])
e.g. db.class0.insert([{'name':'阿花',age:28},{name:'阿红',age:26},{name:'阿彪',age:23}])
* _id 为系统自动添加主键,若是本身写_id域则会使用本身写的值。可是该值仍不容许重复。
save 插入数据
db.collectionName.save()
e.g.
db.class0.save({_id:2,name:'八戒',age:17,sex:'m'})
* 在不加_id是使用同 insert
* 若是使用save插入的时候加了_id,则若是_id值不存在则正常插入,若是该值存在,则修改原来内容
* save没法一次插入多个文档
做业 : 练习mongodb的数据库,集合建立删除
mongodb 插入练习
关系型数据库和非关系数据库都有什么特色?
mongodb的优势在哪里?
************************************************************次日
复习 :
数据库建立删除: use 数据库名称
db.dropDatabase()
集合的建立和删除 db.createCollection('name')
db.collectionName.insert()
db.collectionName.drop() 删除
db.collectionName.renameCollection() 重命名
数据库的备份和恢复
mongodump (备份) mongorestore(恢复)
数据库的监测
mongostat mongotop
数据库配置
mongod --dbpath path --port 8888
数据的插入 : insert() save()
=====================================
db.collectionName 集合对象
获取集合对象 : db.getCollection('collection_name')
e.g.
db.getCollection("class0").insert({name:'悟空',age:1700})
查找操做
select ... from tableName where .....
db.collectionName.find() ---> select * from tableName
find(query,field)
功能 : 查找全部符合条件的文档
参数 : query : 筛选条件 至关于where字句
field : 展现的域 至关于select的展现部分
返回 : 返回全部查找到的内容
field 参数 : 选择要展现的域 传一组键值对
键表示域名
值表示是否显示该域 0 表示不显示 1 表示显示
* 若是某个域给定0 则表示不显示该域,其余的域均显示
若是某个域给定1 则表示显示该域 ,其余的域都不显示
* _id 永远默认为显示,除非设置为0
* 除_id外其余域 必须拥有相同的设置,全为0或者全为1
* 若是不写该参数则表示显示全部域内容
e.g. db.class0.find({},{_id:0,name:1,age:1})
query : 以键值对的形式给出查找条件
查找年龄 17
e.g. db.class0.find({age:17},{_id:0})
* 若是不写第一个参数则表示查找全部内容
findOne()
功能参数和find() 彻底相同,只是只返回第一条查找到的文档
e.g. db.class0.findOne({age:17},{_id:0})
query的更多用法
操做符: 使用$符号注明一个特殊字符串,表示必定的含义
e.g. $lt 表示 小于
比较操做符
$eq 等于
e.g. db.class0.find({age:{$eq:17}},{_id:0})
筛选年龄等于17的
=====》 db.class0.find({age:17},{_id:0})
$lt 小于 <
e.g. db.class0.find({age:{$lt:17}},{_id:0})
* mongo中字符串也能够比较大小
$lte 小于等于 <=
e.g. db.class0.find({age:{$lte:17}},{_id:0})
$gt 大于 >
e.g. db.class0.find({age:{$gt:17}},{_id:0})
$gte 大于等于 >=
e.g. db.class0.find({age:{$gte:17}},{_id:0})
$ne 不等于 !=
e.g. db.class0.find({age:{$ne:17}},{_id:0})
* 若是一个文档没有这个age域则显示为不等于
$in 包含
e.g. db.class0.find({age:{$in:[16,17,18]}},{_id:0})
$nin 不包含
e.g. db.class0.find({age:{$nin:[16,17,18]}},{_id:0})
逻辑操做符
$and 逻辑与
年龄小于19 而且 性别为男
db.class0.find({age:{$lt:19},sex:'m'},{_id:0})
年龄小于19 而且 大于15
db.class0.find({age:{$lt:19,$gt:15}},{_id:0})
e.g. db.class0.find({$and:[{age:17},{name:'Lei'}]})
$or 逻辑或
e.g.
db.class0.find({$or:[{age:{$lt:22}},{name:'悟空'}]},{_id:0})
db.class0.find({$or:[{age:{$lt:18}},{age:{$gt:30}}]},{_id:0})
$not 逻辑非
e.g. db.class0.find({age:{$not:{$eq:17}}},{_id:0})
$nor 既不也不 (表示列表集合中的条件都不具有)
db.class0.find({$nor:[{age:{$gt:18}},{sex:'m'}]},{_id:0})
条件混合
(年龄小于20 或者 姓名为阿红) 而且 性别为女的人
db.class0.find({$and:[{$or:[{age:{$lt:20}},{name:'阿红'}]},{sex:'w'}]},{_id:0})
年龄小于等于17 或者 (姓名大于Tom 而且 年龄大于100)
db.class0.find({$or:[{age:{$lte:17}},{name:{$gt:'Tom'},age:{$gt:100}}]},{_id:0})
数组查找 :
查看数组中包含某一项的
e.g. db.class1.find({hobby:'吃'},{_id:0})
$all
查找一个数组中同时包含多项的文档
e.g. db.class1.find({hobby:{$all:['拍电影','代言']}},{_id:0})
查找hobby数组中既有拍电影,又有代言的文档
$size
查找数组元素个数为指定个数的文档
e.g. db.class1.find({hobby:{$size:3}},{_id:0})
查找hobby数组中包含三项的文档
数组切片显示
$slice
对数组切片显示
e.g.
db.class1.find({hobby:{$size:3}},{_id:0,hobby:{$slice:2}})
显示数组的前两项
e.g.
db.class1.find({hobby:{$size:3}},{_id:0,hobby:{$slice:[1,2]}})
跳过第一项,显示后面两项
其余查找方法:
$exists
判断一个域是否存在
e.g. 查找存在sex域的文档
db.class0.find({sex:{$exists:true}},{_id:0})
e.g. 查找不存在sex域的文档
db.class0.find({sex:{$exists:false}},{_id:0})
$mod
作除数余数查找
e.g.
查找年龄 被2除余1的文档
db.class0.find({age:{$mod:[2,1]}},{_id:0})
$type
查找指定数据类型的文档
e.g. 查找hobby中包含数据类型为 2 的数据的文档
db.class1.find({hobby:{$type:2}},{_id:0})
数据类型对照:
https://docs.mongodb.com/manual/reference/operator/query/type/
进一步的信息筛选
distinct()
功能 : 查看一个集合中某个域值的覆盖范围
e.g. 查看集合中age域的值都有哪些
db.class0.distinct('age')
pretty()
功能 : 将查询结果格式化显示
e.g. db.class0.find().pretty()
limit(n)
功能: 查询结果显示前 n条
e.g. 查询结果显示前3个
db.class0.find({},{_id:0}).limit(3)
skip(n)
功能 : 显示时跳过前n条
e.g. 显示时跳过前三条
db.class0.find({},{_id:0}).skip(3)
count()
功能 :对查找结果计数统计
e.g. 统计sex 为 m的文档数量
db.class0.find({sex:'m'},{_id:0}).count()
sort({键:1/-1})
功能 : 对查找结果排序
1 表示按照升序排列, -1 表示按照降序排列
对查找结果按照年龄升序排列
db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1})
复合排序 : 当第一排序项相同的时候,按照第二排序项排序
db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1,name:-1})
函数的连续使用
获取集合中年龄最小的三个文档
db.class0.find({},{_id:0}).sort({age:1}).limit(3)
删除文档
delete from tableName where ....
db.collectionName.remove(query,justOne)
功能 : 删除指定的文档
参数 : query : 筛选要删除的文档, 相似where子句
用法同 查找操做
justOne :布尔值 默认 false 表示删除全部筛选数据
若是赋值为true 则表示只删除第一条复合的文档
e.g.
db.class0.remove({$or:[{age:{$exists:false}},{age:{$gt:100}}]})
删除第一个复合条件的文档
db.class0.remove({sex:{$exists:false}},true)
删除集合中全部文档
db.collectionName.remove({})
练习:
1. 建立一个数据库 名字grade
use grade
2. 数据库中建立一个集合名字 class
3. 集合中插入若干数据 文档格式以下
{name:'zhang',age;10,sex:'m',hobby:['a','b','c']}
hobby: draw sing dance basketball football pingpong
computer
db.class.insert([
{name:"zhang",age:10,sex:'m',hobby:['a','b','c']},
.....
])
4. 查找练习
查看班级全部人信息
find()
查看班级中年龄为8岁的学生信息
find({age:8})
查看年龄大于10岁的学生信息
find({age:{$gt:10}})
查看年龄在 4---8岁之间的学生信息
find({age:{$gte:4,$lte:8}})
找到年龄为6岁且为男生的学生
find({age:6,sex:'m'})
找到年龄小于7岁或者大于10岁的学生
find({$or:[age:{$lt:7},age:{$gt:10}]})
找到年龄是8岁或者11岁的学生
find({age:{$in:[8,11]}})
找到兴趣爱好有两项的学生
find({hobby:{$size:2}})
找到兴趣爱好有draw的学生
find({hobby:"draw"})
找到既喜欢画画又喜欢跳舞的学生
find({hobby:{$all:["draw","dance"]}})
统计爱好有三项的学生人数
find({hobby:{$size:3}}).count()
找出本班年龄第二大的学生
find().sort({age:-1}).skip(1).limit(1)
查看学生的兴趣范围
db.class.distinct('hobby')
将学生按年龄排序找到年龄最大的三个
find().sort({age:-1}).limit(3)
删除全部 年级大于12或者小于4岁的学生
remove({$or:[{age:{$gt:12}},{age:{$lt:4}}]})
做业 : 复习 数据的查找 和删除操做
mongo练习
*********************************************************
第三天
查找 find(query,field)
findOne()
操做符 : 比较 $lt $lte $gt $gte $eq $ne $in $nin
逻辑 $and $or $not $nor
数组 $all $size
其余 $exists $type $mod
查找函数 : limit() skip() sort() count() pretty()
其余函数 distinct() getCollection()
删除 remove(query,justOne)
=======================================
修改数据
update tableName set ... where .....
db.collectionName.update(query,update,upsert,multi)
功能 : 修改一个文档
参数 : query : 删选要修改的文档 至关于where子句
用法同查找
update : 将数据更新为何内容 至关于set操做
须要使用修改器操做符
upsert : bool值 默认为false 表示若是query的文档不 存在则没法修改
若是设置为true 表示若是query的文档不存在则根据query和update参数插入新的文档
multi : bool值 默认为false 若是有多条符合筛选条件 的文档则只修改第一条
若是设置为true 则修改全部符合条件的文档
e.g. 将阿红年龄改成24
db.class0.update({name:'阿红'},{$set:{age:24}})
e.g. 若是筛选数据不存在则插入一个新的文档
db.class0.update({name:'阿花'},{$set:{age:18,sex:'w'}},true)
e.g. 能够同时修改多条匹配到的文档
db.class0.update({sex:'w'},{$set:{age:20}},false,true)
修改器操做符
$set
修改一个域的值
增长一个域
e.g. db.class0.update({name:'阿红'},{$set:{sex:'w'}})
$unset
删除一个域
e.g. 删除文档的sex和age域 (后面数字习惯写1,0 都表示删除)
db.class0.update({name:'八戒'},{$unset:{sex:0,age:0}})
$rename
修改一个域的名称
e.g. 修改全部的sex域为gender
db.class0.update({},{$rename:{sex:'gender'}},false,true)
$setOnInsert
若是update操做插入新的文档,则补充插入内容
e.g. 若是插入数据则同时插入sex和tel域内容
db.class0.update({name:'阿华'},{$set:{age:21},$setOnInsert:{sex:'m',tel:'123456'}},true)
$inc
加减修改器
e.g. 年龄减2
db.class0.update({age:{$lt:18}},{$inc:{age:-2}},false,true)
* $inc 可加正数 负数 小数均可以
$mul
乘法修改器
e.g.
db.class0.update({name:'阿华'},{$mul:{age:-0.5}})
* $mul 可乘以正数 负数 小数均可以
$min
设定最小值 : 若是筛选的文档指定的域值小于min值则不修改,若是大于min值则改成min值
e.g.
db.class0.update({},{$min:{age:19}},false,true)
$max
设置最大值 : 若是筛选的文档指定至于大于max值则不变,若是小于max值则修改成max值
e.g.
db.class0.update({},{$max:{age:20}},false,true)
数组修改器
$push 向数组中添加一项
e.g.
db.class1.update({name:"Abby"},{$push:{score:30}})
$pushAll 向数组中添加多项
e.g.
db.class1.update({name:"Jame"},{$pushAll:{score:[10,20]}})
$each 逐个操做
e.g. 利用each添加多项
db.class1.update({name:"Lily"},{$push:{score:{$each:[10,5]}}})
$position
选择数据位置进行操做 必须和each合用
e.g.
db.class1.update({name:"Lucy"},{$push:{score:{$each:[10,10],$position:1}}})
$sort
对数组进行排序 必须和each合用
e.g.
db.class1.update({name:"Lily"},{$push:{score:{$each:[],$sort:1}}})
$pull 从数组中删除一个元素
e.g.
db.class1.update({name:'Lucy'},{$pull:{score:10}})
$pullAll 从数组中删除多个元素
e.g.
db.class1.update({name:'Jame'},{$pullAll:{score:[10,20]}})
$pop 弹出数组中的一项
e.g.
db.class1.update({name:'Lily'},{$pop:{score:-1}})
* -1表示弹出数组中的第一项 1 表示弹出最后一项
$addToSet 向数组中插入一个元素,可是该元素不能和其余元素重复
e.g. 若是已经存在66则没法插入,若是不存在则插入66
db.class1.update({name:'Lily'},{$addToSet:{score:66}})
数据类型补充
时间类型
mongo中存储时间的格式 :ISODate
方法1 自动生成当前时间
db.class2.insert({title:'Python入门',date:new Date()})
方法2 生成当前时间
db.class2.insert({title:'Python精通',date:ISODate()})
方法3 将生成时间变为字符串存储
db.class2.insert({title:'Python AI',date:Date()})
指定时间的转换
ISOData()
功能 : 生成mongo时间类型
参数 : 若是不加参数则生成当前时间
参数格式 "2018-11-11 11:11:11"
"20180101 11:11:11"
"20181102"
e.g.
db.class2.insert({title:'Python 爬虫',date:ISODate("20180101 11:11:11")})
时间戳获取
e.g.
db.class2.insert({title:'PythonWeb',date:ISODate().valueOf()})
null
1. 若是某个域存在却没有值能够设置为null
e.g. db.class2.insert({title:'Python 秘籍',price:null})
2.表示某个域不存在能够经过null进行匹配
e.g. db.class2.find({date:null},{_id:0})
能够查找到date不存在的文档
Object类型 (值是一个文档)
*当使用外层文档引用内部文档的时候能够用用 . 的方法引用
在使用时须要加上引号
e.g.
db.class2.find({'publication.publisher':'人民教育'},{_id:0})
e.g.
db.class2.update({title:'Python数据'},{$set:{'publication.price':58.8}})
数组的下标引用
使用一个数组时,可使用 .序列下标 的方式使用数组具体的某一项。一样须要用引号
e.g. db.class1.update({name:'Lily'},{$set:{'score.0':60}})
e.g. db.class1.find({'score.0':{$gt:90}})
文档查找结果的有序性
能够经过[]取查找结果序列的某一项
db.class1.find({},{_id:0})[1]
练习 :
使用以前的grade数据库
1. 将小红的年龄变为8岁 兴趣爱好变为 跳舞 画画
{$set:{age:8,hobby:['dance','draw']}}
2. 追加小明兴趣爱好 唱歌
{$push:{hobby:'sing'}}
3. 小王兴趣爱好增长 吹牛 打篮球
{$pushAll:{hobby:['吹牛','basketball']}}
4. 小李增长爱好,跑步和唱歌,可是不要和之前的重复
{$addToSet:{hobby:{$each:['running','sing']}}}
5. 该班全部同窗年龄加1
update({},{$inc:{age:1}},false,true)
6. 删除小明的sex属性
{$unset:{sex:0}}
7. 删除小李兴趣中的第一项
{$pop:{hobby:-1}}
8. 将小红兴趣中的画画爱好删除
{$pull:{hobby:'draw'}}
索引
指的是创建指定键值及所在文档中存储位置的对照清单。使用索引能够方便咱们进行快速查找,减小遍历次数,提升查找效率
mongo中如何建立索引
ensureIndex()
功能 : 建立索引
参数 : 索引类别,索引选项
e.g.
db.class0.ensureIndex({'name':1})
* 1表示为该域建立正向索引,-1 表示逆向索引
* _id 域会自动建立索引
查看一个集合中的索引
db.class0.getIndexes()
删除索引
dropIndex()
功能 : 删除索引
参数 : 删除索引的名称
e.g. 能够经过索引名称或者索引键值对删除
db.class0.dropIndex('name_1')
db.class0.dropIndex({name:1})
dropIndexes()
功能 : 删除全部索引
e.g. db.class0.dropIndexes()
索引类型
复合索引
根据多个域建立一个索引
db.class0.ensureIndex({name:1,age:-1})
数组索引
若是对某个数组域建立索引,那么表示对数组中的每一个值均建立了索引,经过数组中单个值查询,也是索引查询
db.class1.ensureIndex({'score':1})
子文档索引
若是对一个域建立索引,值是一个文档则子文档也会同时造成索引
若是对子文档某一个域进行索引建立,则只有经过子文档中的该域查找时为索引查找
e.g.
db.class2.ensureIndex({'publication.pulisher':1})
覆盖索引
查找时只获取索引项的内容,而没必要去获取原数据中的其余内容,这样就不去链接原来的数据直接返回便可
e.g. name为索引项,显示也只要name域
db.class0.find({name:'Lily'},{_id:0,name:1})
惟一索引
建立索引时但愿索引域的值均不相同,也能够据此限制一个域的值
e.g.
db.class0.ensureIndex({name:1},{'unique':true})
*当对某个域建立了惟一索引后,即不容许在插入相同的值的文档
稀疏索引(间隙索引)
只针对有指定域的文档建立索引表,没有该域的文档,不会插入到索引表中
e.g.
db.class2.ensureIndex({'date':1},{sparse:true})
索引约束 :
1.影响数据的插入,删除,修改操做。当数据发生改变时,索引表必须同步更新
2.索引也是须要占用必定的空间资源
综上 : 当数据库大量的操做是插入,修改,删除操做,而非查询操做时,不适合建立索引。数据量比较小时,考虑到空间成本也不适合建立索引。即便适合建立索引的状况,也不是索引越多越好。
聚合
多数据文档进行整理统计
db.collectionName.aggregate()
功能 : 聚合函数,配合聚合条件进行数据整理统计
参数 : 聚合条件
聚合操做符
$group 分组 和分组操做符配合使用肯定按什么分组
++++++++++++++++++++++++++++++++++
分组操做符 (和$group配合)
$sum 求和
统计每组个数
db.class0.aggregate({$group:{_id:'$gender',num:{$sum:1}}})
聚合 分组 按gender分组 统计结果名
统计每组年龄和
db.class0.aggregate({$group:{_id:'$gender',num:{$sum:'$age'}}})
$avg 求平均数
求平均年龄
db.class0.aggregate({$group:{_id:'$gender',num:{$avg:'$age'}}})
$min 求最小值
求每组姓名的最小值
db.class0.aggregate({$group:{_id:'$gender',name:{$min:'$name'}}})
$max
求每组姓名的最大值
db.class0.aggregate({$group:{_id:'$gender',name:{$max:'$name'}}})
$first
返回每组第一个文档指定域值
db.class0.aggregate({$group:{_id:'$gender',name:{$first:'$name'}}})
$last
返回每组最后一个文档指定域值
db.class0.aggregate({$group:{_id:'$gender',name:{$last:'$name'}}})
+++++++++++++++++++++++++++++++++++
$project
用于修饰文档的显示结构
e.g.
db.class0.aggregate({$project:{_id:0,name:1,age:1}})
e.g.
db.class0.aggregate({$project:{_id:0,Name:'$name',Age:'$age'}})
$match 过滤数据
操做符的值同find的query
db.class0.aggregate({$match:{name:{$gt:'Tom'}}})
$skip 跳过前几条文档
db.class0.aggregate({$skip:2})
$limit 显示几条文档
db.class0.aggregate({$limit:2})
$sort 排序
db.class0.aggregate({$sort:{name:1}})
聚合管道
将前一个聚合操做的结果给下一个聚合操做继续执行
db.collectionName.aggregate([聚合1,聚合2,.....])
e.g. match---> project ---> sort
db.class0.aggregate([{$match:{name:{$gt:'Tom'}}},{$project:{_id:0,name:1,age:1}},{$sort:{name:-1}}])
e.g. group ---> match
db.class0.aggregate([{$group:{_id:'$gender',num:{$sum:1}}},{$match:{$nor:[{_id:'m'},{_id:'w'}]}}])
做业练习 :
使用以前的grade数据库
增长分数域 score:{'chinese':88,'english':78,'math':98}
1. 按照性别分组统计每组人数
aggregate({$group:{_id:'$sex',num:{$sum:1}}})
2. 按照姓名分组,过滤出有重名的同窗
aggregate([{$group:{_id:'$name',num:{$sum:1}}},{$match:{num:{$gt:1}}}])
3. 统计每名男生的语文成绩
aggregate([{$match:{sex:'m'}},{$project:{_id:0,name:1,'score.chinese':1}}])
4. 将女生按照英语分数降序排列
aggregate([{$match:{sex:'w'}},{$sort:{'score.english':-1}}])
******************************************************
第四天
修改
update(query,update,upsert,multi)
修改器 : $set $unset $rename $setOnInsert $inc $mul
$min $max
$push $pushAll $each $pull $pullAll $position
$pop $addToSet $sort
数据类型 Date() ISODate() valueOf()
null 的使用
Object :经过 . 取内部文档
经过 . 取数组索引
索引建立 ensureIndex()
聚合操做 aggregate()
聚合操做符 $group $match $project $limit $skip $sort
========================================================
固定集合
mongo中能够建立大小固定的集合,称之为固定集合,固定集合的性能出色,适用于不少场景
好比 : 日志处理, 临时缓存
特色 : 插入速度快
顺序查询速度快
可以淘汰早期数据
能够控制集合空间
建立:
db.createCollection(collectionName,{capped:true,size:10000,max:1000})
size :设置固定集合的大小 kb
max : 最多能容纳多少文档
e.g.
建立一个最多包含三条文档的集合
db.createCollection('log',{capped:true,size:10,max:3})
文件存储
数据库存储文件的方式
1. 在数据库中以字符串的方式存储文件在本地的路径
优势 : 节省数据库空间
缺点 : 当数据库或者文件位置发生变化即须要相应修改数据库内容
2. 将文件已二进制数据的方式存放在数据库里
优势:文件存入数据库,数据库在,文件即不会丢失
缺点: 当文件较大时,数据库空间占用大,提取困难
mongo中 使用GridFS方法 大文件存储
GridFS : 是mongodb中大文件存储的一种方案,mongo中认为大于 16M的文件为大文件
方案解释:
在mongodb数据库中 建立两个集合 共同完成对文件的存储
fs.files : 存储文件的相关信息,好比:文件名 文件类型
fs.chunks : 实际存储文件内容,以二进制方式分块存储。将大文件分为多个小块,每块占一个空间
mongofiles -d dbname put file
数据库 要存储的文件
*若是数据库不存在则自动建立
fs.files
{ "_id" : ObjectId("5b0770c169d72e1e3a6eebda"), "chunkSize" : 261120, "uploadDate" : ISODate("2018-05-25T02:11:13.986Z"), "length" : 8313457, "md5" : "4b39deb86dcb6ece44ef52a69dcd6e1a", "filename" : "xly.zip" }
fs.chunks
{ "_id" : ObjectId("5b0770c169d72e1e3a6eebee"), "files_id" : ObjectId("5b0770c169d72e1e3a6eebda"), "n" : 19, "data" : BinData(0,"wGTrj3......)}
获取数据库中文件
mongofiles -d grid get xly.zip
优缺点 :
优势 : 存储方便,方便数据库移植,对文件个数没有太多限制
缺点 : 读写效率低
游标
为何使用游标
1. 防止网络拥塞,形成数据传输慢
2. 提升用户解析体验,能够后端解析
var cursor = db.class0.find() 建立游标
cursor.hasNext() 查看是否有下一个数据
cursor.next() 获取下一个数据
经过Python 操做mongodb数据库
Python ---》 mongodb编程接口 pymongo
安装
sudo pip3 install pymongo
操做步骤
1. 建立mongo数据库的连接对象
conn = MongoClient('localhost',27017)
2. 生成数据库对象
db = conn.stu
3. 生成集合对象
my_set = db.class0
4. 增删改差索引聚合操做
插入数据 insert() insert_many() insert_one()
save()
删除数据
remove({},multi = True)
multi 默认为True 表示删除全部符合条件的数据
设置为False 表示只删除一条
数据查找
find()
功能 : 查找数据库内容
参数 : 同 mongo shell find()
返回值 : 返回一个游标 ---》 迭代器
cursor 可迭代对象属性函数
next()
count()
limit()
skip()
sort()
mongoshell ---> sort({'name':1})
pymongo ---> sort([('name',1)])
* 进行排序时游标要确保没有被访问过
find_one()
返回值是一个字典
修改操做
update()
参数和mongoshell 中 update相同
update_many() :匹配到多个文档时所有修改
update_one() : 只修改匹配到的第一条文档
* 变成中mongo的数据类型null 能够用Python中的 None替代
索引
建立索引
ensure_index()
create_index()
create_indexes() 建立多个索引
查看集合中的索引
list_indexes()
删除索引
drop_index() 删除某一个索引
drop_indexes() 删除全部索引
聚合操做
aggregate([])
参数 : 与mongoshell中聚合参数写法一致
返回值 : 迭代器 同find的返回值