Mongodb数据库学习

数据库  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的返回值

猜你喜欢

转载自www.cnblogs.com/wcin/p/9119272.html