day01
数据存储阶段:
文件管理阶段(.txt .doc .xls)
优点:
数据可以长期保存
数据有一定格式化规范
可以大量存储
使用简单方便
缺点:
数据一致性差
用户查找修改不方便
数据冗余
数据库管理阶段
优点:
数据组织结构化,降低了冗余
提高了增删改查的效率
便于扩展,方便程序调试做自动化处理
缺点:
数据库的使用专业性强,相对比较复杂
数据:能够输入到计算机中并被识别处理的信息的集合
数据结构:研究组成数据集合中数据之间关系的学科
(计算机原理,计算机网络,数据结构,数据库)
数据库:按照数据结构存储管理数据的仓库
是在数据管理系统软件管理和控制下创建在一定介质上的数据集合
数据管理系统:数据管理软件,用于维护管理数据库
数据库系统:由数据库,数据管理系统,开发工具组成的工具集合
关系型数据库 ---> 二维表
优点:
容易理解,逻辑类似常见的表格
使用方便,都是用sql语句,sql语句非常成熟
数据一致性高,冗余低,完整度好
技术成熟,可以使用外部链接等复杂操作
缺点:
每次操作都与需要SQL语句解析,消耗较大
不能很好的满足并发需求,应对海量数据爆发力不从心
关系型数据库内部存在大量的加锁操作,读写能力受到限制
数据不够灵活,有时会导致结构复杂化
非关系型数据库(Nosql --> not only sql)
优点:
高并发,读写能力强
扩展性强,使用灵活
弱化了数据结构,降低数据一致性
缺点:
通用性差,没有sql那样同一操作语言
操作灵活,容易混乱
没有join等复杂操作,版本更新快
Nosql使用情况
1.数据的一致性要求低
2.处理数据的海量并发
3.数据库大小不容易确定,需要分布扩展
4.给定的数据结构建立非关系模型更加容易
Nosql分类
键值数据库 Redis
列存储数据库
文档数据库 MongoDB
图形数据库
MongoDB数据库(非关系型数据库-->文档数据库)
1.由c++编写的数据库管理系统
2.支持丰富的增删改查功能
3.支持丰富的数据类型
4.支持众多的编程语言接口(python php c++ js c#)
5.在Nosql中技术相对比较成熟
MongoDB安装
自动安装
sudo apt-get install mongodb
默认安装路径
/var/lib/mongodb
配置文件
/etc/mongodb.conf
命令集
/usr/bin /usr/local/bin
whereis 软件名 : 查看一个软件的位置
手动安装
1.下载合适版本的MongoDB
www.mongodb.com --> get MongoDB --> community server
2.选择合适位置解压(/usr/local /opt)
解压后得到MongoDB文件
3.将文件夹下bin文件夹加入到环境变量中
(bin中就是命令集)
PATH=$PATH:/opt/mongodb.../bin
export PATH
将以上写入 /etc/rc.local
4.重启系统
MongoDB 命令
设置数据库存储位置
mongod --dbpath 目录
e.g. mongod --dbpath dbs
设置数据库端口
mongod --port 8080
* 默认27017
mongo --> 进入mongo shell
mongodb的交互模式,用于操作MongoDB数据库
MongoDB数据库组成结构
键值对 --> 文档 --> 集合 --> 数据库
概念对比
mysql 和 MongoDB 含义
database database 数据库
table collection 表/集合
column field 字段/域
row document 记录/文档
index index 索引
创建数据库
use databaseName
e.g. 创建一个stu数据库 -- use stu
* 实际use是选择使用哪个数据库,当选择的数据库不存在时就会自动创建
* 只有向数据中插入数据时数据库才会被真是创建出来,而use后不会马上创建
查看数据库
show dbs
系统数据库
admin:存放用户和权限
local:存放本地化数据
config:存储分片信息
数据库命名规则
1.使用utf-8字符
2.不能含有空格 . / \ "\0" 字符
3.长度不能超过64字节
4.不能和系统数据库重名
* 习惯上使用小写字母,表达数据库的含义
db:mongo系统全局变量,代表当前正在使用的数据库对象
* 当不使用use选择任何数据库时,db表示test。此时插入数据则创建test数据库
备份
mongodump -h dbhost -d dbname -o dbdir
e.g. 将127.0.0.1上的stu数据库被封到bak目录中
mongodump -h 127.0.0.1 -d stu -o bak
恢复
mongorestore -h dbhost:port -d dbname dbpath
e.g. 将stu数据库恢复到127.0.0.1上的student数据库中,student不存在则自动创建
mongorestore -h 127.0.0.1:27017 -d student bak/stu
数据库检测命令
mongostat
insert query update delete :每秒增查改删次数
command :每秒运行命令的次数
flushes : 每秒和磁盘交互次数
vsize :使用虚拟内存大小
检测每个数据读写时长
mongotop
ns total read write
数据集合 总时长 读时长 写时长
删除数据
db.dropDatabase()
创建集合
db.createCollection(collection_name)
e.g. 创建一个叫class1的集合
db.createCollection('class1')
创建集合2
当向一个集合中插入数据的时候,如果这个集合不存在则自动创建
db.collection.insert(...)
集合名称
e.g. db.class2.insert({'name':'lyz'})
查看集合
show collections
show tables
集合的命名规则
1.合法的utf-8字符
2.不能有'\0'
3.不能以system.开头。是系统的包邮前缀
4.不能喝关键字重复
删除集合
db.collection.drop()
e.g. 删除class2集合
db.class2.drop()
集合重命名
db.collection.renameCollection("new_name")
e.g. db.class2.renameCollection('class1')
文档
mongodb中数据的组织形式 --> 文档
MongoDB文档:以键值对的形式组成的类似于字典的数据结构结合,是对数据的一种描述
键:及文档的域
命名规则
1.utf-8格式字符
2.不能有'\0'
3.一个文档中的键不能重复
* 文档中键值对是有序的
* MongoDB严格区分大小写
值:即文档存储数据,也及时MongoDB支持的数据类型
bson ---> json ---> javascript
值类型 数值
整型 整数 1 2 3 -1 -2
布尔类型 true false
浮点型 小数 1.234
Array 数组 [1 2 3 4]
Timestamp 时间戳
Date 时间日期
Object 内部文档
Null 空值 null
String 字符串
Symbol 特殊字符串
Binary data 二进制字符串
code 代码
regex 正则表达式
ObjectId ObjectId对象
db.collection.find()
ObjectId(系统自带)
"_id" : ObjectId("5b...")
_id : 如果在插入一个文档时没有指定_id域,则系统会自动添加该域作为主键。值则是一个ObjectId类型数据
24位 16进制 --> 保证所有的_id值的唯一性
8位的文档创建时间 6位机器id 4位进程id 6位计数器
集合中的文档
* 集合中的文档不一定域的个数相同
* 集合中的文档不一定有相同的域
(关系型数据库:表决定字段。MongoDB中:文档决定域)
集合设计原则
1.集合中的文档,应该尽可能描述同一类内容。有更多相同的域
2.同一类数据信息,不要过多分散集合存放
3.集合中文档的层次不要包含太多
插入文档
db.sollection.insert()
插入单个文档
e.g. db.class0.insert({name:lucy,age:15,sex:'m'})
* 查看插入结果:db.class0.find()
* 文档中键可以不加引号
* _id为系统自动添加主键,如果自己写也可以,但是不能重复
插入多条文档
db.class0.insert([{},{},{}..])
save 插入文档
db.collection.save()
* 如果不使用_id则save用法同insert一样
* 如果加_id项,此时文档已经存在时则会替换原有文档
获取集合对象
db.getCollection("collection_name")
===> db.collection_name
要求:
关系型数据库和非关系型数据库区别
介绍一下MongoDB数据库
复习mysql
练习MongoDB数据库集合的创建删除,文档的插入
****************************************************
day02
非关系型数据库和关系型数据库区别
1.不是以关系模型构建的,结构自由
2.非关系型数据库不保证数据的一致性
3.非关系型数据库可以在处理高并发和海量数据时弥补关系型数据库的不足
4.非关系型数据库在技术上没有关系型数据库成熟也没有sql语句的操作
MongoDB 文档型数据库
=================================================
查找操作
mysql : select * from table where ...
mongo : db.collection.find(query,field)
find(query,field)
功能:查找数据
参数:query 筛选条件,相当于where子句
field 选择要展示的域
query:以键值对的形式给出查找条件
e.g. db.class0.find({age:18})
field:以键值对的形式给出要展示(不展示)的域
域名为键,0为值表示不显示该域
1为值表示显示该域
e.g. db.class0.find({},{_id:0})
* 如果使用0设置某些域不显示则默认其他域显示
* 如果使用1设置某些域显示则默认其他域不显示
* _id 只有设置为0才会不显示否则默认显示
* 除_id 域,其他域必须同时设置为0或者1
findOne(query,filed)
功能:查找符合条件的第一天文档
参数:同find
返回值:查找到的文档
query更丰富用法
操作符:使用$号注明一个特殊意义字符,表达某个特定含义。比如 $gt 表示大于
比较操作符
$eq 等于
db.class0.find({age:{$eq:18}},{_id:0})
$lt 小于
db.class0.find({name:{$lt:"Tom"}},{_id:0})
* 字符串也可以比较大小
$lte 小于等于
db.class0.find({age:{$lte:18}},{_id:0})
$gt 大于
$gte 大于等于
$ne 不等于
$in 包含
$nin 不包含
逻辑操作符
$and 逻辑与
e.g.
db.class0.find({$and:[{age:{$gt:18}},{sex:{$eq:'m'}}]},{_id:0})
db.class0.find({age:{$gt:18},sex:{$eq:'m'}},{_id:0})
$or 逻辑或
e.g.
db.class0.find({$or:[{age:{$gt:18}},{sex:{$eq:'m'}}]},{_id:0})
$not 根据后面条件取反
e.g.
db.class0.find({age:{$not:{$eq:18}}},{_id:0})
$nor 既不也不
e.g.
db.class0.find({$nor:[{age:{$eq:18}},{sex:'m'}]},{_id:0})
练习:
年龄大于等于22且名字为Tom 或者 性别为 m :
db.class0.find({$or:[{age:{$gte:22},name:'Tom'},{sex:'f'}]},{_id:0})
数组
表达:使用中中括号将一定的数据组成的一种数据结构
* 数组中的数据类型可以不同
* 数组是有序的
e.g. 数组值中只要有任意一项大于90即可
db.class2.find({score:{$gt:90}},{_id:0)
$size
通过数组中元素的个数查找
e.g. 查找数组中包含两项的文档
db.class2.find({score:{$size:2}},{_id:0})
$all
查找数组中同时包含多项的文档
e.g. 查找数组同时包含77,69的
db.class2.find({score:{$all:[77,69]}},{_id:0})
$slice
取数组的部分进行显示,在field中声明
e.g. 显示数组跳过第一项显示后面两项
db.class2.find({},{_id:0,score:{$slice:[1,2]}})
其他query查询
$existe
判断一个域是否存在
e.g. 查找域sex存在的
db.class0.find({sex:{$exists:true}},{_id:0})
$mod
余数查找
e.g. 查找年龄除2余1的
db.class0.find({age:{$mod:[2,1]}},{_id:0})
$type
数据类型查找
e.g. 查找age值类型是1的
db.class0.find({age:{$type:1}},{_id:0})
操作符用法文档查找
www.mongodb.com ---> docs ---> search
查找结果的进一步操作
distinct()
功能:查看集合中某个域的取值范围
e.g.
db.class0.distinct("age")
pretty()
功能:将查询结果格式化显示
e.g.
db.class0.find().pretty()
limit(n)
功能:显示查找结果的前n条文档
e.g.
db.class0.find({},{_id:0}).limit(4)
skip(n)
功能:跳过前n条显示后面的内容
e.g.
db.class0.find({},{_id:0}).skip(4)
count()
计数功能 -> 统计查找数量
db.class0.find({},{_id:0}).count()
sort({field:1/-1})
功能:对查找结果排序
参数:以键值对形式给出,键表示按照哪个域排序
1 升序 -1 降序
复合排序
当第一排序项相同时,按照第二排序项排序,以此类推
db.class0.find({},{_id:0}).sort({age:1,name:1})
函数的连续调用 -> 注意函数调用后的返回值
e.g.
db.class0.find({},{_id:0}).sort({age:1}).limit(3)
文档的删除操作
mysql:delete from table where ...
mongodb: db.collection.remove(query,justOne)
remove(query,justOne)
功能:删除文档
参数:query 筛选要删除的文档,相当于where
用法同find
justOne 布尔值 默认为false 表示删除所有符合条件的文档,设置为true 则表示只删除一条
e.g.
db.class0.remove({age:{$not:{$type:1}}})
db.class0.remove({sex:{$exists:false}})
db.class0.remove({age:17},true)
删除一个集合中所有文档
db.collection.remove({})
练习:
创建
创建数据库 名字grade
数据库中创建集合 名字class
集合中插入若干文档
查看年龄大于10岁的学生信息
db.class.find({age:{$gt:10}},{_id:0})
查看年龄8-10岁之间的学生信息
db.class.find({age:{$gt:8},age:{$lt:11}},{_id:0})
db.class.find({age:{$ge:8,$lt:11}})
找到年龄9岁且为男生的学员
db.class.find({age:9,sex:'m'},{_id:0})
找到年龄小鱼7岁或者大于11岁的学生
db.class.find({$or:[{age:{$lt:7}},{age:{$gt:11}}]},{_id:0})
找到年龄8岁或者11岁的学生
db.class.find({age:{in:[8,11]}},{_id:0})
找到有两项兴趣爱好的学生
db.class.find({hobby:{$size:2}},{_id:0})
找到喜欢computer的学生
db.class.find({hobby:'computer'},{_id:0})
找到既喜欢画画,又喜欢跳舞的学生
db.class.find({hobby:{$in:['draw']},hobby:{$in:['dance']}},{_id:0})
db.class.find({hobby:{all:['draw','dance']}})
统计兴趣爱好有3项的学生人数
db.class.find({hobby:{$size:3}},{_id:0}).count()
找到本班年龄第二大的学生
db.class.find({}).sort({age:-1}).skip(1).limit(1)
查看学生兴趣爱好范围
db.class.distinct("hobby")
找到年龄最小的三个同学
db.class.find({},{_id:0}).sort({age:1}).limit(3)
删除年龄小于6岁或者大于12岁的学生
db.class.remove({$or:[{age:{$lt:6}},{age:{$gt:12}}]})
修改操作
mysql:update table set ... where ...
mongodb:db.collection.update(query,update,upsert,multi)
update(query,update,upsert,multi)
功能:修改文档
参数:query 筛选要修改的文档,相当于where,用法同find()
update 将筛选的文档修改成的内容,相当于set。需要配合修改操作符一同使用
upsert 布尔值 默认为false,如果query的文档不存在,则不进行任何操作。设置true如果query的文档不存在,则根据update和query插入新文档
multi 布尔值,默认为false,如果query文档有多条,则值修改第一条。如果设置为true,则修改所有符合条件的文档
修改操作符的使用
$set -> {$set:{sex:"m"}}
修改一个域的值,如果不存在则增加一个域
db.class1.update({name:'阿蓉'},{$set:{age:18,sex:'f'}})
* 每个操作符可以操作多项
$unset -> {$unset:{sex:''}}
删除一个域
db.class1.update({age:55},{$set:{name:'老王'},$unset:{sex:''}})
* 一个修改可以使用多个操作符
$rename
修改域名
db.class1.update({sex:{$exists:true}},{$rename:{sex:'gender'}},false,true)
$setOnInsert
如果第三个参数为true且插入数据,则表示插入新文档的补充内容。如果不插入文档则不起作用
db.class1.update({name:'老王'},{$set:{gender:'m'},$setOnInsert:{tel:'66666'}},true)
只插入 gender 不插入tel
db.class1.update({name:'阿文'},{$set:{gender:'m'},$setOnInsert:{age:32}},true)
新增一条‘阿文’文档,包含name age gender
$inc
加减修改器
db.class1.update({},{$inc:{age:1}},false,true)
$mul
乘法修改器
db.class1.update({name:'老王'},{$mul:{age:2}})
* $inc $mul 参数可以是整数小数正数负数
$min
如果筛选文档指定域值小于min值则不修改,大于min值则修改为min值
---> 相当于给出上限min
db.class1.update({},{$min:{age:40}},false,true)
$max
如果筛选文档指定域值大于max值则不修改,小于max值则修改为max值
---> 相当于给出下限max
db.class1.update({},{$max:{age:18}},false,true)
数组修改器
$push
项数组中添加一项
db.class2.update({name:'小亮'},{$push:{score:99}})
$pushAll
向数组中添加多项
db.class2.update({name:'小明'},{$pushAll:{score:[60,100]}})
$pull
从数组中删除一项
db.class2.update({name:'小明'},{$pull:{score:60}})
$pullAll
从数组中删除多项
db.class2.update({name:'小明'},{$pullAll:{score:[79,100]}})
$each
对多个值进行逐一操作
db.class2.update({name:'小明'},{$push:{score:{$each:[60,100]}}})
$position
指定插入位置
db.class2.update({name:'小红'},{$push:{score:{$each:[5],$position:1}}})
$sort
对数组进行排序
db.class2.update({name:'小明'},{$push:{score:{$each:[],$sort:1}}})
$pop
弹出一项 -> 只能弹出数组两端的数据
1 是最有一项 -1 是第一项
db.class2.update({name:'小明'},{$pop:{score:-1}})
$addToSet
向数组中添加一项,但是不允许添加重复内容
db.class2.update({name:'小红'},{$addToSet:{score:100}})
如果没有100 则添加
时间类型
MongoDB 中支持时间格式 - IOSDate
1.使用 new Date() 生成标准时间
2.使用 IOSDate() 生成当前时间
3.获取计算机时间,生成格式字符串 Date()
IOSDate()
功能:生成MongoDB时间存储类型
参数:不加参数生成当前时间
指定时间格式参数:
"2018-01-01 12:12:12"
"20180101 12:12:12"
"20180101"
db.class0.insert({book:"Python",date:ISODate("2018-07-12 11:23:36")})
时间戳
通过当前的时间生成的一个时间节点标志
valueOf()
生成某个标准时间的时间戳
Null 类型
值:null
1.如果某个域存在却没有值可以设置为null
db.class0.insert({book:"Python编程思想",date:null})
2.在查找时可以找到值为null或者不存在的date域文档
db.class0.find({date:null},{_id:0})
db.class0.find({date:{$exists:false}},{_id:0})
数组的下标操作方式
可以通过 域名.下标 的方式具体操作数组的某一项
> db.class2.find({'score.0':{$gt:90}},{_id:0})
> db.class2.update({name:'小红'},{$set:{'score.0':88}})
内部文档操作 Object
文档内部某个域的值也是一个文档,则这个文档成为内部文档数据类型
* 通过 外部域.内部文档域 的方式应用内部内档中某个域进行操作
> db.class3.find({"book.title":"狂人日记"},{_id:0})
> db.class3.update({name:'老舍'},{$set:{'book.price':34.6}})
查找结果的下标引用
可以通过下标的方式获取查找结果的某一项
db.class1.find({},{_id:0})[2]
练习
使用grade数据库
1.将小红改为8岁,兴趣爱好变为dance draw
db.class.update({name:'小红'},{$set:{age:8,hobby:['draw','dance']}})
2.追加天明兴趣爱好 sing
> db.class.update({name:'天明'},{$push:{hobby:'sing'}})
3.追加小强兴趣爱好 吹牛,打篮球
> db.class.update({name:'小强'},{$addToSet:{hobby:{$each:['吹牛','basketball']}}})
4.小李兴趣爱好多了跑步唱歌,但是要保证不和以前重复
> db.class.update({name:'小冰'},{$addToSet:{hobby:{$each:['running','sing']}}})
5.将所有年龄+1
> db.class.update({},{$inc:{age:1}},false,true)
6.删除天明的sex属性
> db.class.update({name:'天明'},{$unset:{sex:''}})
7.删除小李兴趣中的第一项
> db.class.update({name:'小冰'},{$pop:{hobby:-1}})
8.删除小红兴趣中的画画和唱歌
> db.class.update({name:'小红'},{$pullAll:{hobby:['sing','draw']}})
9.为小红增加一个域,为score:{english:93,chinese:92,match:78}
> db.class.update({name:'小红'},{$set:{score:{english:93,chinese:92,match:78}}})
10.给小红数学成绩+5
> db.class.update({name:'小红'},{$inc:{'score.match':5}})
11.天明的第一爱好改为computer
> db.class.update({name:'天明'},{$push:{hobby:{$each:['computer'],$position:0}}})
索引
指建立指定键值及所在文档中存储位置的对照清单,使用索引可以方便我们进行快速查找,减少数据遍历次数,从而提高查找效率
MongoDB创建所有
ensureIndex({xx:yy},{name:'name1'})
功能:创建索引
参数:索引选项
xx 为对哪个域创建索引
yy 为索引选项 -> 1 -1
{name:'name1'} 设置索引自定义名称 “name1”
对name域创建索引
> db.class1.ensureIndex({name:1})
* 1表示正向索引
* -1表示逆向索引
> db.class1.ensureIndex({age:1},{name:'hahaha'})
getIndexes()
功能:查看某个集合中的索引
> db.class1.getIndexes()
* _id 是系统为每个集合自动创建的索引
* 同一个域不能重复创建相同的索引,一个集合中索引名也不要相同
dropIndex()
功能:删除一个索引
参数:索引名或者索引键值对
> db.class1.dropIndex('hahaha')
> db.class1.dropIndex({name:1})
dropIndexes()
功能:删除所有索引
* 不会删除 _id 索引
> db.class1.dropIndexes()
其他索引类型
复合索引
同时根据多个域创建一个索引
> db.class1.ensureIndex({name:1,age:-1})
根据name和age域查询都为索引查询,比单独创建两个索引更节省空间
数组和子文档索引
如果对某个数组和子文档域创建索引,那么根据数组和子文档的查找均为索引查找
覆盖索引
查找操作获取需要获取的域,只有索引没有其他域。此时索引表可以直接提供给用户想要的内容,提高查找效率
唯一索引
创建的索引,索引域值无重复,此时可以创建唯一索引,唯一索引数据结构更加便于查找
> db.class1.ensureIndex({name:1},{unique:true})
* 当对某个域创建唯一索引,该域就不能再插入重复数据
稀疏索引
只针对有指定域的文档创建索引表,如果某个文档没有该域则不会插入到索引表中
> db.class1.ensureIndex({age:1},{sparse:true})
索引约束
1.索引表也需要占用一定的磁盘空间
2.当数据发送更新时索引表也要随之更新
综上:
1.数据量比较大时更适合创建索引,数据量较小时没有必要付出索引代价
2.频繁进行查找操作而不是更新删除插入操作,此时更适合使用索引
固定集合
MongoDB中可以创建大小固定的集合,称之为固定集合
特点:
插入速度更快,顺序查找更快
可以控制集合的空间大小
能够自动淘汰早起数据
使用:
日志处理
临时缓存
创建
db.createCollection(collection,{capped:true,size:10000,max:100})
capped:true 创建固定集合
size:10000 固定集合大小 字节数
max:100 表示最多多少条文档
*****************************************************
聚合操作
对文档的信息进行整理统计的操作
返回:统计后的文档集合
db.collection.aggregate()
功能:聚合函数,完成聚合操作
参数:聚合条件,配合聚合操作符使用
返回:聚合后的结果
聚合操作符
$group 分组聚合
$sum 求和
> db.class1.aggregate({$group:{_id:'$gender',num:{$sum:1}}})
分组 按gender分组 统计结果,求和每有一个+1
> db.class1.aggregate({$group:{_id:'$gender',num:{$sum:'$age'}}})
按性别年龄求和
$avg 求平均数
> db.class1.aggregate({$group:{_id:'$gender',num:{$avg:'$age'}}})
按性别分组求年龄平局数
$max 求最大值
> db.class1.aggregate({$group:{_id:'$gender',num:{$max:'$age'}}})
按性别分组求年龄最大值
$min 求最小值
> db.class1.aggregate({$group:{_id:'$gender',num:{$min:'$age'}}})
按性别分组求年龄最小值
$project
用于修改文档的显示效果
> db.class1.aggregate({$project:{_id:0,name:1,age:1}})
> db.class1.aggregate({$project:{_id:0,Name:'$name',Age:'$age'}})
相当于find()的第二个参数
$match
过滤想要的数据
> db.class1.aggregate({$match:{age:{$gt:25}}})
相当于find()的query参数
$limit
显示前n条文档
> db.class1.aggregate({$limit:3})
$skip
跳过前n个文档显示
> db.class1.aggregate({$skip:3})
$sort
排序
> db.class1.aggregate({$sort:{age:-1}})
聚合管道
将前一个聚合操作产生的结果交给后一个聚合操作继续使用
db.collection.aggregate({聚合1},{聚合2},{聚合3}...)
> db.class1.aggregate([{$match:{gender:'m'}},{$sort:{age:1}},{$project:{_id:0}}])
文件存储
1.存储路径
将文件放在本地路径(网络路径)下,然后数据库中存储该文件的查找路径
优点:节省数据库空间
缺点:当数据或文件位置发生变化时文件即丢失
2.将文件转换为二进制,存储文件本身
数据库支持二进制数据格式
将文件转换为二级制格式,然后存入数据库中
优点:数据库和文件绑定,数据库在文件即在
缺点:占用数据库空间大,存取效率低
MongoDB存储文件本身
* 如果是小文件建议转换二进制直接插入
* 如果是大文件建议使用GridFS方案存储
GridFS方案解释
1.在MongoDB一个数据库中使用两个集合配合存储文件
2.fs.files 用来存储文件的相关信息,为每一个文件创建一个文档,存储文件名,文件大小,存入时间
3.fs.chunks用来分块存储文件的实际内容,Binary data 数据类型
存储方法
mongofiles -d dbname put file
数据库 要存储的文件
* 数据库不存在会自动穿件数据库
* 数据库中会自动创建fs.files fs.chunks两个集合
* 用一个文件fs.files中的_id值等于fs.chunks中域files_id域的值
提取方法
mongofiles -d dbname get file
GridFS方案优缺点
优点:存储方便,提供较好的命令支持和编程接口
缺点:存取效率低
游标
mongo shell 中获取游标
* mongo shell中支持JS代码,可以通过JS获取游标,进而获取数据库操作结果
e.g.
var cursor = db.class1.find()
cursor.next() 获取下一条结果
cursor.hasNext() 才开是否有下一个对象
通过python操作 MongoDB
pymongo模块 第三方模块
安装:
sudo pip3 install pymongo
操作步骤
1.连接数据库,生成数据库连接对象
conn = pymongo.MongoClient("localhost",27017)
2.选择要操作的数据库,生成数据库对象(__setitem__)
db = conn.stu
db = conn["stu"]
3.获取集合对象
myset = db.class0
myset = db["class0"]
4.通过集合对象调用mongodb数据库操作
5.关闭数据库连接
conn.close()
插入文档
insert() 插入数据 功能同mongo shell
insert_many() 插入多条
insert_one() 插入一条
save() 插入数据,通过_id可以修改
查找操作
find()
功能:对数据库进行查找
参数:同mongo shell find()
返回值:返回游标对象
cursor 属性函数
limit()
skip()
count()
sort()
pymongo : sort([("age", -1),("name",-1)])
mongo shell : sort({age:-1,name:-1})
next()
* 如果通过for 或者 next 操作了游标对象,再调用limit,skip,sort 会报错(游标指针发送变化,不在是在第一个)
limit,skip,sort 会对游标对象进行修改,不再是以前的游标对象
find_one()
用法同mongo shell 中的 findOne()
返回的是个字典
修改操作
update(query,update,upsert=False,multi=False)
update_many()
update_one()
删除操作
remove(query,multi=True)
索引操作
ensure_index() 创建索引
list_indexes() 查看索引
drop_index() 删除索引
drop_indexes() 删除所有索引
创建索引
index = myset.ensure_index('name')
创建复合索引
index = myset.ensure_index([(name,-1),(age,1)])
删除索引
myset.drop_index('name_1')
创建特殊索引
index = myset.ensure_index('name',name='yahaha',unique=True,sparse=True)
查看集合中的索引
for i in myset.list_indexes():
print(i)
聚合
aggregate([])
参数: 和mongoshell中写法一致
返回值 : 返回一个迭代器同find
pymongo文件存取操作
1.连接数据库,获取相应的数据库对象
2.通过gridfs.GridFS(db)获取集合对象(代表存储文件的两个集合)
3.通过find()查找文件返回游标
4.通过循环遍历游标获取指定文件对象,read()读取文件内容写入本地
以二进制的方式存储文件
import bson.binary