MogoDB学习笔记day01

第一天

MongoDB (芒果数据库)

数据存储阶段

文件管理阶段  (.txt  .doc .xls)

优点:  使用简单,展现直观,
    可以长期保存数据
    可存储数据量比较大

缺点:  查找不方便
    容易造成数据冗余
    数据格式不规范
    
数据库管理阶段

优点:将数据结构化存储,降低冗余
      提高了增删改查效率
      方便扩展,方便程序调用
      
缺点:数据库往往需要指令或语句操作,相对复杂

几个概念

数据 : 能够输入到计算机中并被识别处理的信息的集合

数据结构 : 组成一个数据集合的数据之间的关系

数据库 : 按照一定的数据结构,存储数据的仓库。数据库是在数据库管理系统和控制下,
在一定介质的数据集合

数据库管理系统 : 数据库管理软件 ,用于建立维护操作数据库

数据库系统:由数据库和数据库管理系统等开发工具组成的集合

关系型数据库 : 采用关系模型(二维表)来组织数据结构的数据库 

Orcale  DB2  SQLServer Mysql SQLie

优点:容易理解,逻辑类似常见的表格
    使用方便,都使用SQL语句,sql语句非常成熟
    数据一致性高,冗余低,数据完整性好,便于操作
    技术成熟,功能强大,支持很多复杂操作

缺点: *每次操作都要进行sql语句解析,消耗较大
       *不能很好地满足并发需求,特别是海量数据爆发,
    关系型数据库读写能力会显得不足
       *关系型数据库往往每一步都要进行加锁的操作,也造成了数据库的负担
       *数据一致性高,有时也会使数据的存储不灵活
    
非关系型数据库(NoSql ------> not only sql)

优点 : 高并发 ,读写能力强
    弱化数据结构一致性,使用更加灵活
    有良好的可扩展性
缺点 : 通用性差,没有sql语句那样通用的语句
    操作零活,导致容易出错和混乱
    没有外键关联等复杂的操作

Nosql 的使用情况

1.对数据存储灵活性要求高,一致性要求低
2.数据处理海量并发,要求瞬间效率速度比较高
3.数据比较容易建立Nosql模型
4.网站临时缓冲存储,爬虫应用

Nosql分类
1.键值型数据库  Redis
2.文档型数据库  MongoDB
3.列存储数据库  HBase
4.图形数据库    


MongoDB数据库

标签:  非关系型数据库          文档型数据库     最像关系型的非关系型数据库

特点:
    1.是由C++编写的数据库管理系统
    2.支持丰富的数据操作,增删改查索引聚合
    3.支持丰富的数据类型
    4.使用方便,可以很好地扩展,相对比较成熟
    5.支持众多的编程语言接口  (python PHP c++ c#)

要求:
    1.关系型数据库和非关系型数据库各自有什么特点
     1. 关系型数据库:
           优点:
         * 容易理解,逻辑类似于常见的表格
         * 使用方便,都使用SQL语句,sql语句非常成熟
         * 数据一致性高,,冗余低,数据完整性好,便于操作
             * 技术成熟,功能强大,支持很多复杂操作
       缺点:
             * 每次操作都要进行sql语句解析,消耗比较大
         * 不能哼好的满足并发需求,特别是海量数据爆发
           关系型数据库读写能力会显得不足
           关系型数据库往往每一步都要进行加锁的操作,也造成了数据的负担
         * 数据一致性高,有时也会是数据的存储不灵活
         
     2. 非关系型数据库:
        优点:
           * 高并发,读写能力强
           * 弱化数据结构一致性,使用更灵活
           * 有良好的可扩展性

        缺点:通用性差,没有sql语句那样通用的语句
    操作零活,导致容易出错和混乱
    没有外键关联等复杂的操作
               * 通用性插,没有sql语句那样通用的语句
           * 操作灵活,导致容易出错和混乱
           * 没有外间关联等复杂的操作
           
        
    2.MongoDB是一个什么样的数据库
       文档型数据  非关系型数据库  最像关系型数据库的非关系型数据库
       特点:
        1.是由c++编写的数据库管理系统
        2.支持丰富的数据操作,增删改查索引聚合
        3.支持丰富的数据类型
        4.使用方便,可以很好地扩展,相对比较成熟
        5。支持众多的编程语言借口 (python PHP c++ c#)


MongoDB的安装

自动安装
sudo apt-get install mongodb

默认安装位置 : /var/lib/mongodb
配置文件位置 : /etc/mongo.conf
命令集: /usr/bin    /usr/local/bin


手动安装
1.下载安装包  
www.mongodb.com
2.解压安装包
/usr/local    /opt
3.将解压后的MongoDB文件夹中的bin目录添加到环境变量
PATH=$PATH:/opt/mongo..../bin
export PATH
将以上两句写入启动脚本  /etc/rc.local
4.重启

MongoDB 命令

设置数据库存储位置
mongod --dbpath  目录

e.g. 将存储路径设置为dbs
    mongod --dbpath bds

设置数据库监听端口
mongod --port 8080
* 默认监听端口 27017

mongo
进入数据库交互界面

mongo shell : 用来操作mongodb数据库的界面,在这里可以使用mongo
语句操作数据库的内容

退出 mongo shell : quit()    exit    ctrl-c

组织结构: 键值对 --> 文档 --> 集合-->数据库

--------------------------------
   id    |  name  |    age
--------------------------------
    1    |  Lily  |    17       
--------------------------------
    2    |  Mike   |    18
--------------------------------

(
 'id':1,
 'name':'Lily',
 'age':17
)

(
 'id':2,
 'name':'Mike',
 'age': '18'
)

mysql 和 mongodb 概念对比

mysql         mongodo     含义
 
database      database    数据库

table         collection  表/集合

cloumn        field       字段/域

row           document    记录/文档

index         index       索引

三个表
1.用户信息      1
1.朋友圈内容    多     多
2.其他用户点赞,评论   多

{id:xxx,'name':'zhan',age:12,pyq:[{data:xxx,content:xxx,image:[1,2,3],zan:[id1,id2],p1:[{data:xx,con:xxx},{},{}]},{}]}


创建数据库
use databaseName

e.g.  创建一个名字为stu的数据库
use stu
* use实际为选择使用哪个数据库,当数据库不存在时会自动创建
* use后并不会立即创建出数据库,而是需要等到插入数据时数据库才会创建

查看系统中的数据库:
show dbs

系统数据库说明
admin : 存储用户信息
local : 存储本地数据
config : 存储分片信息

数据库的命名规则
1.使用utf-8字符 (mongo默认之后utf-8)
2.不能含有 空格 . / \  '\0'  字符
3.长度不能超过64字节
4.不能和系统数据库重名

db: mongodb的全局量,代表当前正在使用的数据库
*如果不选择任何数据库,db代表test,直接插入数据就会建立test
数据库


数据库的备份和恢复

e.g. 将本机test数据库备份到bak目录下
备份  mongodump -h host -d dbname -o bak

恢复 mongorestore -h dbhost:port -d dbname path
e.g. 将test数据库恢复到本机的res数据库中(res不存在自动创建)
tarena@tedu:~/mongodb$ mongorestore -h 127.0.0.1:27017 -d res bak/test

数据库的监测

mongostat   监测数据库运行数据

    insert query update delete:   每秒增查改删的次数
    flushes    每秒和磁盘交互的次数
    vsize  虚拟内存
    res    物理内存
    time   时间

mongotop   监测数据库读写时长

ns     数据表
total  总时间
read   读时间
write  写时间

db.dropDatebase()
删除db所代表的数据库

课外:
标识符命名方法
python 中习惯用下划线链接 socket_server

大驼峰方法: SocketServer
小驼峰方法: sOCKETsERVER
匈牙利方法: iKonw


创建集合 

方法1:
db.createCollection(collection_name)

例:创建class1集合
    db.createCollection('class1')

方法2:
当想一个集合中插入数据时如果集合不存在则自动创建
db.collection_name.insert(...)

查看数据库中的集合

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. 将class 集合重命名为 class0
db.class.renameCollection('class0')

文档

MongoDB中的数据的组织形式   -->文档

MongoDB 文档 :是以键值对的形成的一组数据。类似python中
        字典描述数据的方式

键 : 即文档的域,表达了一个键值对的含义

键的命名规则:
    1.UTF-8格式字符串
    2.不能使用'\0'
    3.一个文档中键不能重复
    
值 : 即文档存储的数据。
* 文档中键值对是有序的
* 文档中键值对严格区分大小写
mongo 文档的数据格式 bson
bson   ---> json  ---> Javascript

mysql 支持的数据类型  :字符,数字,日期时间,枚举


Mongo中数据类型
类型                  值

整型                  整数 1  2   3
布尔类型          true  false
浮点型                小数

Array                 数组

Date              时间日期
Timestamp             时间戳

String              字符串
Symbol              特殊字符串
Binary data           二进制字符串

Null                  null
Object                内部文档(对象)
code                  js代码
regex                 正则子串
ObjectId          自动生成ID标记

 "_id" : ObjectId("5ba07692bebd2ef8b41dab68")

 _id : 当mongodb插入文档时如果不指定_id域则自动生成id域。
 值如果不自己制定即会自动生成一个ObjectId值

 5ba07692bebd2ef8b41dab68

 24 位 使用ObjectId经过算法处理保证其唯一性

 8 位 文档创建事件  6位  机器id   4 位进程id  6位计数器


集合中的文档
    
1.集合中的文档不一定有相同的域
    * 个数不同
    * 域不相同
    * 数据类型可能不相同
2.集合中的文档各自比较独立,相互并不影响


集合创建原则
 1.集合中的文档要描述同一类事物
 2.数据库中同一类数据尽量集中文档存放在相同的集合
 3.集合中的文档嵌套层数不要太多

插入文档

db.collection.insert()
功能: 插入一个文档
参数: 要插入的文档

插入单个文档
e.g.
db.class0.insert({'name':'Lucy','age':18,'sex':'w'})

*插入操作中键可以不加引号
*查看插入结果 db.class0.find()
*_id值可以自己插入 ,但是不能重复

插入多条文档
 插入多条文档时,参数用中括号,里面放入多个文档

e.g.
 db.class0.insert([{'name':'Alex',age:19,sex:'m'},{name:'Andy',age:18,sex:'w'}])


其他插入方法

 db.class0.insertOne()
   e.g.
   db.class0.insertOne({'name':'black',age:24,'sex':'m'})

 db.class0.insertOne()
   db.class0.insertOne({name:'god',age:11,sex:'w'},{name:'haha',age:19,sex:'w'})

save插入文档

db.collection.save()

如果正常插入与insert用法相同
e.g.
 db.class0.save({name:'Allen',age:'18',sex:'m'})
 db.class0.save([{name:'Sunny',age:17,sex:'w'},{name:'Alice',age:16,sex:'w'}])


如果插入数据时 有_id 域 且_id域数据存在时则会修改原文档,
如果该值不存在则正常插入

db.class0.save({_id:2,name:'Maey',age:20,sex:'w'})

获取集合对象方法
db.class0.insert()   ===> db.getCollection('class0')


作用:
1. 对‘要求’问题进行总结,描述
2. 练习数据库的创建删除,集合创建删除
3. 练习数据库的插入操作
4. 复习mysql基本增删改查操作 

========================day 02================================

复习:
1.非关系型数据库和关系型数据库的区别
   * 不是以关系模型构建的,结构比较自由
   * Nosql不保证数据的一致性
   * Nosql弥补了关系型数据库的一些不足,比如高并发,海量数据处理
   * Nosql读写能力强
   * Nosql技术还在不断的快速发展,功能没有关系型数据库成熟强大

2.Mongodb  文档型非关系型数据库
    创建数据库: use databasename
    删除数据库: db.dropDatabase()
    创建集合: db.create.Collection('class')
           db.class1.insert()

    删除集合: db.collection.drop()
    集合重命名:   db.collection.renameCollection()
    
    查看数据   show dbs
    查看集合   show collections
           show tables

    数据备份   mongodump  -h host -d dbname -o bak
    数据恢复   mongorestore  mongorestore -h dbhost:port -d dbname path

    插入文档   inert()   save()


查找操作:

mysql : select * from table where ...

mongodb : db.collection.find(query,field)

查找所有内容
db.collection.find()  ----> select * from table

find(query,field)
功能: 查找文档
参数: query 查找条件,相当于where字句
       field 查找的域
返回值: 返回查找到的所有文档

query : 以键值对的方式传递参数,如果是空{}表示查找所有内容
    例:查找所有性别为w的文档
    db.class0.find({'sex':'w'})

field : 以键值对的方式给出要查找(不查找)的域,以域名为键,以0,1
    为值分别表示不查找和查找

* 如果某一个或多个域设置为0 表示这些域不查找,其他域均查找
* 如果某一个或多个域设置为1 表示这些域查找,其他域均不查找

* _id  除非设置为0, 否则均会查找
* 除_id域其他与不能够有的设置为1 有的设置为0

e.g. 查找结果只有name域
db.class0.find({sex:'w'},{_id:0,name:1})

findOne(query,field)
功能: 查找第一条符合条件的文档
参数: 同find
返回值: 返回查找到的文档


query更多的筛选用法

操作符: 使用$符合注明的一个特殊字符串,表达一定的含义,比如$lt 表示小于

比较操作符使用:

$eq 等于  =
    e.g.  查找年龄等于18
     db.class0.find({age:{$eq:18}},{_id:0})
    ===》db.class0.find({age:18},{_id:0})

$lt 小于 <
    e.g. 查找年龄小于20的
    db.class0.find({age:{$lt:20}},{_id:0})
    e.g. 插找姓名小于Tom的
    db.class0.find({name:{$lt:'Tom'}},{_id:0})

* 在mongodb中字符串可以比较大小

$lte 小于等于 <=
    e.g. 查找年龄小于等于18的
    > db.class0.find({age:{$lte:18}},{_id:0})


%gt  大于  >
    e.g. 查找年龄大于16,小于19的
    db.class0.find({age:{$gt:16,$lt:19}},{_id:0})

* 在mongodb中所有的{},[]中都可以写多个条件。但根据参数的不同表达的意思不一样

$gte  大于等于 >=
    e.g. 查找年龄大于等于19 的
    db.class0.find({age:{$gte:19}},{_id:0})

$ne   不等于  !=
    e.g. 查找年龄不等于19 的
    > db.class0.find({age:{$ne:19}},{_id:0})
    e.g. 查找年龄不等于‘m’的
    db.class0.find({sex:{$ne:'m'}},{_id:0})

* 如果某个域不存在,使用ne查找也会找到该域不存在的文档

$in  包含
    e.g. 查找年龄在[17,19,19]中的数据
    > db.class0.find({age:{$in:[17,18,19]}},{_id:0})

$nin 不包含
    e.g. 查找年龄不在[17,18,19]中的数据
    db.class0.find({age:{$nin:[17,18,19]}},{_id:0})

逻辑操作符

$and 
1.在query 如果写多个条件默认即为and关系
    e.g.
    db.class0.find({age:{$lt:18},sex:'m'},{_id:0})
    ==>
    db.class0.find({$and:[{age:{$lt:18},sex:'m'}]},{_id:0})

$or 逻辑或
    e.g. 年龄大于18 或年龄小于16 
    db.class0.find({$or:[{age:{$lte:16}},{age:{$gt:18}}]},{_id:0})
    e.g. 年龄小于18 或者是女的 
    db.class0.find({$or:[{age:{$lte:18}},{sex:'w'}]},{_id:0})

$not 逻辑非
    e.g.性别不是男的
    db.class0.find({sex:{$not:{$eq:'w'}}},{_id:0})
    e.g.年龄不小于18的
    db.class0.find({age:{$not:{$lt:18}}},{_id:0})

$nor not (a or b)  ===   (not a) and (not b)

    e.g. 性别不是男的,年龄不小于18
    db.class0.find({$nor:[{sex:'m'},{age:{$lt:18}}]},{_id:0})

逻辑条件混合

(年龄大于17 并且为男生)   或者  姓名叫Abby
db.class0.find({$or:[{age:{$gt:17},sex:'m'},{name:'Abby'}]},{_id:0})

(年龄不大于18 或者为女性) 并且姓名大于Lucy
db.class0.find({$and:[{$or:[{age:{$not:{$lt:18}}},{sex:'w'}]},{name:{$gt:'Lucy'}}]},{_id:0})


Array  数组
[1,2,3,4]
* 数组是有序的数据集合
* mongo中数组也可以有多重数据元素集合

查找数组中包含某一条件的元素
e.g.  只要数组中包含元素小于60的元素即可查询过滤
db.class1.find({score:{$lt:60}},{_id:0})

$all: 
e.g.   查找同时包含49 67的文档
db.class1.find({score:{$all:[49,67]}},{_id:0})

$size
通过数组元素个数查找
e.g.  通过元素个数为3的文档
db.class1.find({score:{$size:3}},{_id:0})

$slice
显示数组指定项
e.g. 显示数组前两项
 db.class1.find({},{_id:0,score:{$slice:2}})


e.g.  跳过第一个显示后面两个
 db.class1.find({},{_id:0,score:{$slice:[1,2]}})


$exists
通过某个域是否存在筛选
e.g.:查找不存在sex域的文档
db.class1.find({sex:{$exists:false}},{_id:0})

$mod
余数查找
e.g.: 查询年龄为奇数的数据
db.class1.find({age:{$mod:[2,1]}},{_id:1})
e.g.   查询年龄为偶数的数据
db.class1.find({age:{$mod:[2,0]}},{_id:0})

$type
找出指定数据类型的文档

例: 名字为字符串类型   string:2
      db.class1.find({name:{$type:2}},{_id:0})
      score为数组(但内部数据属于double类型)  double:1
      db.class1.find({score:{$type:1}},{_id:0})
      age 为int型 但是被自动转化为double类型   double:1
      db.class1.find({age:{$type:1}},{_id:0})


查找结果的操作函数

db.collection.distinct(field)
功能: 查看某个域的值范围
返回值: 一个列表(无重复元素)

pretty()
功能:格式化显示查询结果
例: db.class0.find().pretty()

limit(n)
功能:显示前n条结果
e.g.  显示查询结果前3条数   
   db.class0.find({},{id:0}).limit(3)

skip(n)
功能: 跳过前n条显示后面的查询结果
e.g. 显示查询结果(跳过前3条)
    db.class0.find({},{_id:0}).skip(3)

    db.class0.find({},{_id:0}).limit(4).skip(2)
    ===》
    db.class0.find({},{_id:0}).limit(4).skip(2)


count()
功能:统计查询结果数量
e.g. 年龄大于18 的文档有几条
db.class0.find({age:{$gt:18}},{_id:0}).count()
* 在统计数量时要给出一定query条件呢
e.g. 统计性别为w的文档个数
db.class0.find({sex:'w'},{id:0}).count()

sort({field:1/-1})
功能:对查找结果进行排序
参数: 以键值对表示按照哪个field排序
       1 表示升序 ,-1表示降序
e.g.  按照年龄升序排序
   db.class0.find({},{_id:0}).sort({age:1})
e.g.  按照年龄降序排序
   db.class0.find({},{_id:0}).sort({age:-1})


e.g. 复合排序  按照年龄升序排序,年龄相同按照姓名降序排序
   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 where
        alter table t1  drop  字段
    
mongodb : db.collection.remove(query,justOne)

remove(query,justOne)
功能 : 删除文档
参数 :query  用法同find
       justOne  布尔值 默认为false 表示删除所有符合条件的文档
                设置为 true 表示只删除一条

e.g. 删除所有不存在sex域的文档
db.class1.remove({sex:{existe:false}})
e.g. 删除性别为女中的第一条文档
db.class1.remove({sex:'w'},true)

删除class1中所有文档
db.class1.remove({})

练习:
1.创建数据   名称 grade
2.创建集合   名称 class
3.集合中插入若干文档 文档格式

{name:'zhangsan',age:10,sex:'m',hobby:['a','b']}
年龄范围 6-15
爱好选择 : draw sing dance basketball football
pingpang  computer  每个同学选择2-5项

4. 查找练习
查找班级所有学生信息
    db.class.find()
查找班级中年龄为8岁的学生信息
    db.class.find({age:8},{_id:0})
查找班级中年龄大于10岁的学生信息
    db.class.find({age:{$gt:10}},{_id:0})
查看班级中年龄在8-11岁之间的学生信息
    db.class.find({age:{$gt:8},age:{$lt:11}},{_id:0})
查看班级中年龄10岁且为男生的学生信息
    db.class.find({age:10,sex:'m'},{_id:0})
查看班级中小于7岁或者大于14岁的学生
    db.class.find({$or:[{age:{$lt:7}},{age:{$gt:8}}]},{_id:0})
查看班级中年龄为8岁或者11岁的学生
    db.class.find({age:{$in:[8,11]}},{_id:0})
找到有两项兴趣爱好的学生
    db.class.find({hobby:{$size:2}},{_id:0})
找到兴趣中 有draw的学生
    db.class.find({hobby:'draw'})
找到即喜欢画画又喜欢跳舞的学生
    db.class.find({hobby:{$all:['draw','dance']}})
    db.class.find({hobby:'draw',hobby:'dance'})
统计兴趣有4项的学生的人数
    db.class.find({hobby:{size:4}},{_id:0})
找出本班年龄第二大的学生
    db.class.find({},{_id:0}).sort({age:-1}).skip(1).limit(1)
查看本班学生兴趣爱好涵盖哪些方面
    db.class.distinct('hobby')
找到年龄最大的三个同学
    db.class.find().sort({age:-1}).limit(3)
删除所有年龄大于16岁或者小于7岁的学生除非他的爱好有三项以上
    db.class.remove({$or:[{age:{$gt:16}},{age:{$lt:7}}],hobby:{$lt:{$size:3}}})


修改文档
mysql: update table set ...where ...
mongodb:
    db.collection.update(query,update,upsert,multi)
功能:  修改文档
参数:  query   筛选条件   用法同find
    update  要求改成什么内容  通常配合修改操作符(修改器)使用
    upsert  布尔值,默认是false 如果query没有筛选到文档则不作任何操作
        如果设置为true 则如果query没有筛选到文档则query和update内容插入新的文档

    multi   布尔值  默认为false  表示如果有多条符合条件文档则只修改第一条;
        如果设置为true   则表示修改所有符合条件的文档

将 Tom的年龄修改为18
    db.class0.update({name:'Tom'},{$set:{age:18}})

将 Jame 插入到文档中
    db.class0.update({name:'Jame'},{$set:{age:15}},true)

将所有年龄小于17的修改为18
    db.class0.update({age:{$lt:17}},{$set:{age:18}},false,true)


作业: 
    1.练习查找操作 
    2.练习删除和修改操作
    3.将三国改为mongo版,按照mysql课上练习进行增删改查操作

*******************************day 03********************************

复习

查找操作  find(query,field)
      findOne(query,field)
      
查找操作符   比较运算符 $eq   $lt  $gt  $ne  $lte  $gte  $in  %nin   
         逻辑运算符 $and  $or  $not  $nor
         数组       $all   $size      $slice
             其他       $exists    $mod   $type

查找函数: pretty()   limit()  skip()   sort()  count()   
           db.class.dictinct('域名')   #  查看某个域的取值范围

删除操作: remove(query,justOne)

修改操作:update(query,updata,upsert,multi)

=====================================================================

补充: 通过find查找结果,可以使用序列号获取某一项
    e.g.  获取查找结果中的第三项
      db.class0.find({},{_id:0})[2]

 修改操作符(修改器)

 $set  
    修改一个域的值
    e.g.  修改Lily的年龄为17
        db.class0.update({name:'Lily'},{$set:{age:17}})

    增加一个域
    e.g. 为jame增加sex域
    db.class0.update({name:'jame'},{$set:{sex:'m'}})

$unset
    删除一个域
    e.g.  删除god 的 sex域
    db.class0.update({name:'god'},{$unset:{sex:''}})

$rename
    修改域的名称
    e.g.   将sex域名改为gender
    db.class0.update({},{$rename:{sex:'gender'}},false,true)

$setOnInsert
    如果使用update插入了文档,则将该修改器内容作为插入文档的一部分
    相当于补充插入
    e.g.   插入 lisimeng 年龄18 性别w 电话 123456
    db.class0.update({name:'lisimeng'},{$set:{age:18},$setOnInsert:{gender:'w',tel:'123456'}},true)

$inc
    加法修改器
    e.g. 所有人年龄加1
    db.class0.update({},{$inc:{age:1}},false,true)
* 参数可以使正数负数,整数小数

$mul
    乘法修改器
    e.g.   所有人年龄乘以2
    db.class0.update({},{$mul:{age:0.5}},false,true)
* 参数可以使正数负数,整数小数

$min
    如果筛选文档的指定域值小于min值则不修改,大于min
    值则修改为min值
     e.g.    Alex age 如果大于19则修改为19
     db.class0.update({name:'Alex'},{$min:{age:19}})    
    
$max
    如果筛选文档的指定域大于max值则不修改,小于max值
    则修改为max值
    e.g.    Alex  age 如果小于25则修改为25
     db.class0.update({name:'Alex'},{$max:{age:25}})


$push
    向数组中添加一项
    e.g. 给小红 score 数组添加一项91
    db.class1.update({name:'小红'},{$push:{score:91}})

$pushAll
    向数组中添加多项
    e.g. 给小乔score 数组中添加 94,10
   > db.class1.update({name:'小乔'},{$pushAll:{score:[94,10]}})


$pull 
    从数组中删除一项
    e.g. 删除小红score 数组中78 
    db.class1.update({name:'小红'},{$pull:{score:78}})

$pullAll
    从数组中删除删除多项
    e.g.
    db.class1.update({name:'小乔'},{$pullAll:{score:[94,10]}})

$each
    对多个值逐个进程操作
    例 分别插入 99 10
    db.class1.update({name:'小乔'},{$push:{score:{$each:[99,10]}}})

$position
    指定位置
    例 将67插入到数组1号位置
    db.class1.update({name:'小明'},{$push:{score:{$each:[67],$position:1}}})


$sort
    数组排序
    e.g. 排序score数组 按降序排序
    db.class1.update({},{$push:{score:{$each:[],$sort:-1}}})
$pop
    弹出一项   1表示弹出最后一项 
              -1 表示弹出第一项
    e.g. 弹出小乔的最后一项
    db.class1.update({name:'小乔'},{$pop:{score:1}})
    e.g. 弹出小明的第一项
    db.class1.update({name:"小明"},{$pop:{score:-1}})

$addToSet
    向数组中添加一项,但是不能添加重复内容
    e.g. 如果数组中没有81,则添加81
    b.class1.update({name:'小刚'},{$addToSet:{score:81}})

   
时间数据类型

mongo中存储时间大多为 ISODate

存储当前时间方法
    1. new Date()  自动生成当前时间
     e.g.
     db.class2.insert({book:'python入门',data:new Date()})
    2. ISODate()   自动生成当前时间
     e.g.
     db.class2.insert({book:'python精通','date':ISODate()})
    3.Date()    将系统时间转化为字符串
     e.g.
     db.class2.insert({book:'python疯狂',date:Date()})

指定时间
    ISODate()
    功能: 生成mongo标准时间类型数据
    参数: 如果不传参默认为当前时间
           传参表示指定时间
            “2018-01-01 12:12:12”
        “20180101 12:12:12 ”
        "20180101"
    e.g.
      db.class2.insert({book:'python奔溃',date:ISODate('2018-07-01 11:15:56')})

时间戳
    valueOf()
    获取某个时间的时间戳
    db.class2.insert({name:'python涅槃',date:ISODate().valueOf()})

Null 类型
1. 如果某个域存在没有值 可以赋值为null
   e.g.
   db.class2.insert((book:'python死去活来',pirce:null))

2. 可以查找某个域不存在的情况
   e.g. 如果date域不存在也能find到
   db.class2.find({date:null})

Object(内部文档)

文档内部某个域的值还是一个文档数据则这个文档就是内部文档数据类型

通过使用外部文档域名,引用内部文档域名的方式使用内部文档


e.g. 
   db.class3.find({'book.title':'狂人日记'})

e.g.
   db.class3.update({'book.title':'围城'},{$set:{price:48.8}})
  
通过数组下标直接操作某一项

e.g.  查找数组中第一项(注意加引号)
    db.class1.find({'score.0':{$gt:90}},{_id:0})

练习
使用之前的grade数据库

1.将小红年龄改为12岁,兴趣爱好变为跳舞画画
 db.class.update({name:'cui'},{$set:{age:12,hobby:['dance','draw']}})
2.追加小明爱好唱歌
 db.class.update({name:'li'},{$push:{hobby:'sing'}})
3.追加小王兴趣爱好,吹牛,打篮球
db.class.update({name:'xiao'},{$pushAll:{hobby:['吹牛','打篮球']}})
4.小李兴趣多了跑步和唱歌,但是要确保和以前不重复
db.class.update({name:'zhao'},{$addToSet:{hobby:'sing',hobby:'run'}})
5.将班级所有男同学的年龄加1
db.class.update({sex:'m'},{$inc:{age:1}},false,true)
6.删除小明的sex属性
db.class.update({name:'li'},{$unset:{sex:''}})
7.修改小刘的年龄为15,如果不存在该同学则添加,同时要添加兴趣爱好和性别男
db.class.update({name:'yang'},{$set:{age:15},$setOnInsert:{sex:'m',hobby:['sing','dance']}},true)

8.删除小李兴趣中第一项
db.class.update({name:'xiao'},{$pop:{hobby:-1}})
9.删除小红爱好中的画画和跳舞
db.class.update({name:'cui'},{$pullAll:{hobby:['draw','dance']}})


索引

是指建立指定键值及所在文档存储位置的对照清单,使用索引可以方便我们进行快速查找
减少遍历次数提高查找效率

ensureIndex()
功能: 创建索引
参数: 索引域和索引选项

e.g.根据 name 域 创建索引
    db.class0.ensureIndex({name:1})

* 1 表示正序索引,   -1 表示逆序索引

查看集合中索引
db.collection.getIndexes()

自定义索引名称
db.collection.ensureIndex({},{name:'myIndex'})

db.class.ensureIndex({age:1},{name:'ageIndex'})

删除索引
db.colletion.dropIndex('index')
功能: 删除索引
参数: 要删除的索引名称或者键值对
e.g.
db.class.dropIndex({name:1})
db.class.dropIndex('ageIndex')

db.collection.dropIndexes()
功能: 删除所有索引

*_id 是系统自动创建的主键索引,不能删除

索引类型

    符合索引
    根据多个域创建多个索引
 e.g.
  db.class.ensureIndex({name:1,age:-1},{name:'name_age'})

数组索引 ,子文档索引
 如果对某个域的值为数组或者子文档的域创建索引,那么通过数组或者子文档
 中某一项进行查找也是索引查找

 e.g.  如果对score 创建了索引那么该查找就是索引查找
 db.class1.ensureIndex({'score':1})
 db.class1.find({'score.1':88})


唯一索引
创建索引的域要求值不能重复,
    e.g.
    db.class1.ensureIndex({name:1},{name:'nameIndex',unique:true})

* 当对某个域创建了唯一索引就不能插入重复的值

稀疏索引(间隙索引)

只针对有索引域的文档创建索引,没有该域的文档不会插入到索引表
db.class1.ensureIndex({age:1},{sparse:true})

索引约束
  * 索引表需要占用一定的数据磁盘空间
  * 当对数据进行增 删 改 查等写入操作时索引也需要更新,降低了数据修改的
  效率

综上 :数据量较小时不适合创建索引,当数据库进行频繁的修改操作而不是查找操作
时也不适合创建索引。针对一个集合并不是创建索引越多越好。

聚合操作
    对文档的筛选结果进行整理统计
    db.collection.aggregate()
    功能:完成聚合操作
    参数: 聚合条件   ---》 聚合操作符

聚合操作符

$group  分组聚合  需要配合具体的分组统计选项
    $sum : 求和
    e.q.    
    db.class0.aggregate({$group:{_id:'$gender',num:{$sum:1}}})

    { "_id" : "m", "num" : 6 }
    { "_id" : null, "num" : 1 }
    { "_id" : "w", "num" : 5 }
    分别求男女生年龄的和
    db.class0.aggregate({$group:{_id:'$gender',num:{$sum:'$age'}}})

    { "_id" : "m", "num" : 105 }
    { "_id" : null, "num" : 19 }
    { "_id" : "w", "num" : 91 }

$avg: 求平均数
    分别求男女生年龄的平均数
    > db.class0.aggregate({$group:{_id:'$gender',avg:{$avg:'$age'}}})
    { "_id" : "m", "avg" : 21 }
    { "_id" : null, "avg" : 19 }
    { "_id" : "w", "avg" : 18.2 }
    
$max: 最大值 
     分别求男女生年龄的最大值
     db.class0.aggregate({$group:{_id:'$gender',max:{$max:'$age'}}})
     { "_id" : "m", "max" : "18" }
     { "_id" : null, "max" : 19 }
     { "_id" : "w", "max" : 19 }

$min 分比求男女生年龄的最小值
     db.class0.aggregate({$group:{_id:'$gender',min:{$min:'$age'}}})
     { "_id" : "m", "min" : 18 }
     { "_id" : null, "min" : 19 }
     { "_id" : "w", "min" : 17 }

$project 
    修改文档的显示效果
    > db.class0.aggregate({$project:{_id:0,name:1,age:1}})

{ "name" : "Alice", "age" : 18 }
{ "name" : "Jame", "age" : 18 }
{ "name" : "lisimeng", "age" : 18 }

    > db.class0.aggregate({$project:{_id:0,Name:'$name',Age:'$age'}})

{ "Name" : "Lily", "Age" : 18 }
{ "Name" : "Lucy", "Age" : 19 }
{ "Name" : "Tom", "Age" : 19 }

$match
 数据筛选
   $match值得用法同query一致
   e.g. 过滤年龄大于18岁的数据文档
   db.class0.aggregate({$match:{age:{$gt:18}}})

$limit
 筛选前几条文档
 筛选前三条数据
  db.class0.aggregate({$limit:3})

$skip
 跳过几条文档显示
  e.g. 跳过前三条显示后面的数据文档
  db.class0.aggregate({$skip:3})

$sort
 将数据排序
 将年龄按升序排序
 db.class0.aggregate({$sort:{age:1}})


聚合管道:

聚合管道指的是将上一个集合的操作结果给下一个聚合继续操作

db.collection.aggregation({聚合},{},{}....)

db.class0.aggregate([{$match:{gender:'m'}},{$project:{_id:0}},{$sort:{age:1}}])

{ "name" : "Jame", "age" : 18, "gender" : "m" }
{ "name" : "lisimeng", "age" : 18, "gender" : "m", "tel" : "123465" }

db.class0.aggregate([{$group:{_id:'$name',num:{$sum:1}}},{$match:{num:{$gt:1}}}])
{ "_id" : "Jame", "num" : 2 }

作业: 练习数据库的修改和索引操作
       练习数据库的聚合操作
       操作符复习 

*******************day 04**********************


复习:
1.修改操作
update(query,update,upsert,multi)


修改器   $set   $unset    $rename   $setOnInsert
       $inc  $mul  $max   $min
       $push  $pushAll  $pull  $pullAll
       $each  $position  $sort
       $pop  $addtoSet

时间类型: new Date()
           Date()
       ISODate()
       valueOf()

Null类型:  null
        * 表示某个域的值没有意义
        * 匹配某个域不存在

Object类型: 通过外部域名,内部文档域名

索引:提高查询效率

ensureIndex()   创建索引
dropIndex()     删除索引
dropIndexes()   删除多个索引

类型:复合索引    唯一索引    稀疏索引

聚合操作:

aggregate([])

聚合操作符:
    $group  $sum  $avg  $min  $max
    $project
    $match
    $limit
    $skip
    $sort
===========================================


固定集合

mongodb中可以创建大小固定的集合,称之为固定集合

特点:能够淘汰早期数据
      插入和顺序查找速度快
      可以控制集合的空间大小

使用: 临时缓冲
       日志处理
    
创建固定集合
    db.createCollection(collection,{capped:true,size:100,max:1000})

    capped: true  表示创建固定集合
    size  : 表示指定集合的大小  字节
    max  : 表示集合存放文档上限
* size max 两者取最低

e.g.创建名为log的固定集合,size为1000 ,最多存3条文档
  db.createCollection('log',{capped:true,size:1000,max:3})

文件存储:
1.存储文件路径 (通常文件较大)
  e.g.
  db.log.insert({filename:'三只广告牌.mp4',size:982.8,path:'/home/tarena//三支广告.mp4'})


优点:  节省数据库空间
        操作简单快捷
缺点:  当数据库或者文件位置放生变化时需要修改数据库内容

2.存储文件本身
  将文件以二进制的形式存储到数据库中
  优点: 数据库在文件在,不会受到迁移等影响

  缺点: 占用数据库空间大
     存取效率低

GridFS   存储大文件

大文件: 在Mongodb中认为 >16M的文件为大文件

GridFS 方法
    在mongodb中以两个集合配合的方法存储文件
    fs.files  :  存储文件相关信息(文件名,文件类型)
    fs.chunks  : 分块存储文件实际内容

存储文件格式
mongofile -d dbname put file

dbname: 要将文件存入的数据库,如果不存在则自动创建
file  : 要保存的文件

     e.g.
    mongofiles -d grid put 三块广告牌.mp4


 fs.files文件结构
{ "_id" : ObjectId("5ba452de69d72e14da68505b"), 
"chunkSize" : 261120, 
"uploadDate" : ISODate("2018-09-21T02:10:11.370Z"),
"length" : 982823909,
"md5" : "0ece20f2b5936daf5e77ababb285ef57",
"filename" : "三块广告牌.mp4" }


提取文件:
 mongofiles -d dbname get file 

 e.g.
 mongfiles -d grid get 三块广告牌

优缺点:

优点 : 操作方便,提供较好的存储命令,使用数据库存储文件方便移植

缺点 : 读写效率低 

游标 cursor

通过获取操作数据库的返回结果,得到返回结果对象。

通过游标可以进一步获取操作结果数据

将返回结果赋给一个js 变量,作为查找结果游标
var cursor = db.class0.find()

查看是否有下一个结果
cursor.hasNext()

获取下一个结果
cursor.next()


python  --> pymongo 模块

安装:  sudo pip3 install pymongo

操作步骤
1.创建mongodb的数据库的连接对象

conn = pymongo.MongoClinet('localhost',27017)

2.生成数据库对象(__setitem__ __getitem__  把属性取值变为类似于字典取值的属性)

db = conn.stu
db = conn['stu']
     
3.生成集合对象

myset = db.class0
myset = db['class0']

4. 集合操作(增删改查索引聚合)
  

5.关闭数据库连接
conn.close()

 插入操作   
  insert()
  insert_many()
  insert_one()
  save()

查找操作
find()
功能:查找数据库内容
参数:同mongo shell find()
返回值: 返回一个结果游标

find_one()
功能: 查询第一条符合条件的文档
参数:同find()
返回值:返回一个字典

* 在pymongo中所有操作符的用法同mongo shell相同
只是操作时加引号,以字符串的方式写入python代码


cursor 对象的属性

next()
limit()
skip()
count()
sort()
pymongo  -> sort([('age',1),('name',-1)])
mongo shell  ->  sort({age:1,name:-1})

* 使用for 或者next 使用游标位置不再指向开头位置
的时候,调用limit  skip  sort 就会报错

修改操作
update(query,update,upsert=False,multi=False)

update_many()
update_one()


删除操作:
remove(query,multi = True)
multi默认是True表示删除所有query过滤文档
设置为False表示只删除第一个

python 中 True ==> ture
          False ==> false
      None ==> null


索引操作

ensure_index()
list_indexes()
drop_index()
drop_indexes()

聚合操作
aggregate([])
参数: 和mongo shell 一样
返回值: 返回和find()函数相同的游标对象


聚合练习

grade数据库 class集合

1.为所有人添加score域值为{'chinese':88,'math':77,'english':78}
2.按照性别分组,统计每组人数
3.统计每名男生的语文成绩
4.将女生按照英语成绩降序排列

pymongo 实现 gridfs存储

import gridfs

GridFS()
功能:生成grid数据库对象

存储小文件

import bson

你可能感兴趣的:(MongoDB,Nosql,MongoDB)