MongoDB

MangoDB 非关系型 文档型数据库:( 最接近 关系型数据库 的 非关系型数据库)
1、 是一个文档型 非关系数据库
2、 由C++ 编写的 数据库系统
3、 支持丰富的 查询操作
4、 支持众多编程语言的 接口(python ruby c++ c# PHP 等)
5、 使用简单 ,便于部署
6、 支持的 数据格式丰富
7、 支持分布式(一个数据库放在多台主机上 联合使用(即存储空间大)) 扩展

MongoDB 安装:
自动安装:
sudo apt-get install mongodb
默认安装位置 : /var/lib/mongodb
配置文件 : /etc/mongodb.conf
命令集(可执行文件 的集合) :/usr/bin

手动安装:
    1、下载对应系统的安装包 : www.mongodb.com
    2、选择安装目录(/usr/local/opt) 选择一个位置将安装包解压(tar )
    3、进入解压后的文件夹,将 bin 目录 添加到环境变量
        PATH=$PATH:/usr/test/mongdb/bin
        exit PATH
        将以上这两句添加到 linux 自启动执行脚本(系统重启时自动启动程序)
        /etc/rc.local  或者  /etc/bash.bashrc  或其他自启动脚本
    4、重启系统
        reboot
        source /etc/bash.bashrc
    5、设置数据库的存储位置
        sudo mkdir -p /data/db

指令: mongd --dbpath db # (将当前文件下的 db 文件夹设置为 数据库默认存储位置的文件夹)

mongodb 端口号 27017
    设置mongdb 默认端口号
       mongd --port 8888

mongo 
    mongo shell 表示进入到mongodb 交互模式 
            注意 : mongodb 交互模式支持 JavaScript 脚本语言直接编程

指令 :
mongod : 制定数据库的存储位置
mongo shell : 进入到mongodb 交互模式中

mongdb 支持的数据类型:
字符串
整型 : 整数
布尔型
浮点型 : 小数
数组类型(列表)
时间类型
文档类型 : ?
空值 : null
字符串(symbol 通常表示特殊字符)
时间戳(时间节点)
objectID :
二进制数据 : 可存储视频、音频、图片
代码 : JavaScript
正则表达式 : 特殊的 字符串 匹配表达式

Mysql 数据库 存入数据 的层次:
创建数据库、创建数据表、数据的字段、插入数据

MongoDB 数据库 存储数据的概念 :
MySQL MangoDB 含义

database database 数据库
table collection 表 / 集合(mongodb 称为集合)
column field 列(字段) / 域
row document 一条记录 / 一个文档
index index 索引


id | name | age |

1 | Lily | 17 |

2 | tom | 18 |

以上为在 MySQL 存储 的两条记录


以下为在 MongoDB 中 形成两个文档,相当于每个文档对应一个记录:
{
“_id”:ObjectID(" ID 为 MongoDB随机生成一个ID"),
“name”:“Lily”,
“age”:17
},
{
“_id”:ObjectID(" ID 为 MongoDB随机生成一个ID"),
“name”:“tom”,
“age”:18
}


进入 mongo shell : mongo
退出 mongo shell : quit() or exit
创建数据库 :
use student # 创建一个 student 数据库

  • use 实际的功能 表示你选择使用哪个数据库,如果选择一个不存在的数据库 则 当向这个数据库插入数据时,数据库会自动创建

    show dbs # 查看当前 数据库系统 中存在的数据库 , 类似mysql 中的 show databases
    db.student.insert({name:“Lily”,age:17})

数据库的命名规则 :
1、 原则上是 满足以下几条的任意 UTF-8 格式的字符串
2、 不能还有 空字符""
3、 不能含有 空格、点"."、"/","","\0" 字符(mongodb 是C++ 写的,"\0"代表字符结尾)
4、 习惯上全部小写
5、 不应超过 64 字节
6、 不能使用 admin、local、config 这三个系统已经使用的数据库名
admin 数据库 : 存储用户 和 用户权限的
local 数据库 : 该数据库内的内容不能被复制,只能用于本机操作
config 数据库 : 分片处理时 存储分片信息

db --------》 一个数据库全局量 ,代表你 当前正在使用 的数据库。
当没有任何 正在use 的数据库时,db 默认表示 test 数据库


数据库的备份和恢复 :
备份 : mongodump -h dbhost -d dbname -o dbdir (把 host 主机上的name 数据库 备份在 dir 位置)
mongodump -h 127.0.0.1 -d student -o /home/tarena/TFW (将本机 student 数据库被分到 /home/tarena/TFW文件夹下)

恢复 : 
    mongorestore -h <hostname>:<port> -d dbname <path>  (将path路径下备份的数据库 恢复到hostname主机上的 dbname 数据库上 )
    mongorestore -h 127.0.0.1:27017 -d test /home/tarena/TFW/stu (将stu数据库恢复到本机test数据库上)

数据库的检测 :
mongostat :
insert(每秒插入次数) query(每秒查询次数) update(每秒更新次数) delete(每秒删除次数)
getmore command(每秒运行命令次数) dirty used flushes(每秒向磁盘写入次数)
vsize(使用虚拟内存情况) res(使用物理内存情况) qrw arw net_in net_out conn


mongotop : 检测每个数据库的读写时长
ns(数据表) total(总时长) read(读时长) write(写时长)
admin.system.roles 0ms 0ms 0ms


创建数据库:
use stu
db.stu.insert(“class0”) # 创建一个 stu 数据库 并在数据库中添加一个集合


删除数据库 :
db.dropDatabase() # 由于db 代表当前使用的数据库,故要先使用 要删除的数据库,在执行删除操作
use test
db.dropDatabase() # 删除 test 数据库


集合:
use stu
db.createCollection(“class1”) # 在stu 数据库中 创建一个 class1 集合


插入文档
db.class0.insert({name:“张三”}) # 在 class0 几何中插入 文档
db.class0.insert([{name:“zs”},{name:“ls”}]) # 在class0 中插入 zs ls 两个文档


修改 集合名称
db.collection_name.renameCollection(“new_name”)
例如:
db.class1.renameCollection(“class0”) # 将class1 名称修改为class0

db.getCollection(“collection_name”) 获取表对象,同 db.collection_name.rename(“new_name”)
db.class1.find() <==> db.getCollection(“class1”).find()


查找
db.collection_name.find() —> select * feom table_name;
db.class1.find({},{}) # 查找 class1 中全部内容 相当于 select * from class1

find(query,field) # 相当于 findall()
功能 : 查找所有符合筛选要求的文档
参数 : query : 筛选条件 相当于 where 子句
field : 展示的域 0 表示不展示该域
1 表示展示该域
返回值 : 返回所有符合要求的文档

field : 选择要展示的域
1、 以键值对的形式给每个域赋值0,1 表示是否要显示该域
2、 如果给域设置为 0 ,则其他域 自动为1(显示)
如果给某个域设置为 1 , 则其他域自动设置为 0 (不显示)。 注意两者不能混用
3、 _id 比较特殊,默认为1 ,如果不想显示则设置为0,_id 为0 时,其他的域 可以设置为 1
4、 如果不写该参数,则表示显示所有的域

例如 :
db.class1.find({},{_id:0,name:1,age:1})

query : 查找
1、 以键值对的方式 确定查找条件
2、 如果不写这个参数,则表示查找所有文档

db.class1.find({age:22},{name:1,age:1})    等价于 ---->  select name,age from class1 where age=22;
    查找 class1 集合中 所有年龄为 22 的人,显示 _id 姓名和 年龄

db.collection_name.findone()
功能 : 查找 符合查找条件的第一条文档
参数 : 同 find
返回值 : 返回查找到的文档


query 的更多用法

比较 操作符
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{eq:22}},{}) 等价于 db.class0.find({age:22},{})
# 比较运算符也是用键值的方式,给比较运算符设置一个值,表示相应的关系

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{lt:22}},{}) # 显示年龄小于 22 岁的成员
# 在mongoDB 中字符串也可以比较大小

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{lte:22}},{}) # 查找年龄 小于等于 22 的

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{gt:22}},{}) # 查找年龄 大于 22 的

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{gte:22}}) # 查找年龄 大于等于 22 的

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{ne:22}},{})

  • 如果某个文档没有 age 这个域也会显示为不等于 22

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{in:[22,23,24]}},{}) # 查找年龄 22,23,24 的

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{nin:[22,23]}},{}) # 查找不包含年龄为 22,23 的


逻辑 操作符 : (与或非)

KaTeX parse error: Expected 'EOF', got '#' at position 65: …},{}) #̲ 查找 年龄为 22 且性别为…and:[{age:22},{sex:“m”}]},{})

* 默认 在query 中都好分割的多个条件即为逻辑关系

例如:  查找年龄在20 至 25 之间的
    db.class0.find({$and:[{age:{$gt:20}},{age:{$lt:25}}],{})
    等价于 
    db.class0.find({age:{$ge:20,$lt:25}},{})

KaTeX parse error: Expected '}', got 'EOF' at end of input: …b.class0.find({or:[{age:22},{sex:“m”}]},{}) # 查询年龄为 22 ,性别为 m 的
db.class0.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: or:[{age:{lt:20}},{age:{$gt:25}}]},{}) # 查询年龄小于 20 或 大于 25 的

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{not:{KaTeX parse error: Expected 'EOF', got '}' at position 6: eq:22}̲}},{}) #…and:},{})

条件混合
年龄小于 20 或者 姓名为 阿荣 并且 性别为女的人
db.class0.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: or:[{age:{lt:20}},{name:“啊荣”,sex:“w”}]},{_id:0})


数组查找
db.class1.find({hobby:“python”},{_id:0})

表示 hobby 数组中 含有 python 的文档,_id 不显示

$all 查找数组hobby 中 包含多项的文档

db.class1.find({hobbyL:{$all:["python","game"]}},{_id:0})

查找数组hobby 中 包含 python 和 game 的文档

$size:n 查找数组中 包含 n 个元素的文档

db.class1.find({hobby:{$size:2}},{})

查找 hobby 数组中 包含两个元素的 文档

第二个参数中 :
$slice 显示数组中 前几项

db.class1.find({},{_id:0,hobby:{$slice:2}})    # 显示 hobby 数组中的 前 2 项
db.class1.find({},{_id:0,hobby:{$slice:[1,2]}})   # hobby 中 跳过 1 项,显示跳过后的 2 项 (类似于切片操作)

其他查找方法
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({sex:{exists:true}},{_id:0}) # 查找存在 sex 域的文档
db.class0.find({sex:{$exists:false}},{_id:0}) # 查找 不存在 sex 域的文档

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{mod:[3,0]}},{_id:0}) # 查找被 3 整除余数为 0 的文档

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ss0.find({age:{type:1}},{}) # 查找 age 数据类型为 1(详细可参照 mongodb $type 说明)double 类型的文档


和 查询结果 相关的几个函数
distinct() # 有区别的
功能 : 查看一个集合中 某个域的值所覆盖的范围
db.class0.distinct(“age”) # 查看记录中年龄 包含的所有值,范围为一个列表
db.class1.distinct(“hobby”) # 查看 class1 中数组(列表域)hobby 的覆盖范围

pretty() # 将查询结果 格式化 显示
功能 : 将查询结果 格式化显示 (显示更好看)
db.class0.find().pretty() 将查询结果 整理 漂亮的显示出结果

limit(n)
功能 : 查询结果显示前 n 个文档
db.class0.find().limit(3) # 将查询结果的 前3 条文档显示出来

skip(n)
功能 : 跳过前 n 条文档进行显示
db.class0.find().skip(2) # 显示查询结果 且跳过前 2 条文档

count()
功能 : 对查询条件符合的 文档进行计数统计 输出
db.class0.find().count()

sort({})
功能 :按照制定的字段进行排序
参数 : 键值对 某个域按照升序排序则值为1 , 降序则值为 -1
db.class0.find().sort({age:1}) # 对查询结果 以age 升序的方式进行排序输出
db.class0.find().sort({age:-1}) # 将查询结果 以 age 降序方式进行排序输出

符合排序 : 当第一个排序项 值相等的时候 按照 第二个排序项进行 排序
db.class0.find({},{}).sort({age:1,name:-1})      # 对查找结果进行age降序进行排序,当年龄相同时 按照姓名升序进行排序

联合使用
db.class0.find({},{}).sort(age:1).limit(3) # 查找age 最小的3个成员 (先升序,再取前3个)


删除文档

db.collection_name.remove(query{where条件},justOne(是否删除第一条))
功能 : 删除 collection_name 文档
参数 : query : 定位要删除的文档数据 , 类似于mysql 中 where 子句
用法 和 查找中相同
justOne : 给 bool 值,默认为 false 表示删除所有符合条件的 数据文档
如果赋值为 true 则表示只删除第一条符合条件的文档
db.class0.remove({sex:{$exists:false}}) # 删除所有 不含 sex 域的文档
db.class0.remove({},0) # 删除集合中所有的文档
db.class0.remove({}) # 删除几何中所有的文档


更新文档
mysql 中更新语法 update student set age=16 where name=“张三”;

db.collection_name.update(query,update,upsert,multi)
功能 : 更新一个文档数据
参数 :
query : 条件字句,定位要更新的数据,类似于mysql 中where 语句
用法 同查找({})
update : 将数据更新为 什么内容,相当于 set ,需要配合修改器操作符使用

可选 upsert : bool 值,默认为 false ,表示当定位的文档不存在 则无法修改。
(更新插入) 如果设置为 true 值时,表示如果定位的文档不存在 则插入这条文档

可选 multi : bool 值,默认为 false,表示如果query 匹配的文档有多条,则只修改第一条
如果设置为 true 时,表示query 匹配到的文档 所有都修改。

    示例:
        修改 name:“阿花” 的年龄为19 age:19
        db.class.update({name:"阿花"},{$set:{age:19}},false,false)
        db.class.update({name:"阿泽"},{$set:{age:23,sex:"m"}},true,false) 
            更新插入:姓名 阿泽 的年龄为23 性别为 m 
        
    multi 为 false 时
        当 age 为 22 的有多个文档时,只修改 第一个。
        db.class.update({age:22},{$set:{age:18},true,false)
    multi 为 true 时
        当 age 为 22 的有多个文档时,修改所有的 age 为22 的为18
        db.class.update({age:22},{$set:{age:18}},true,true)

update 
    修改器 :将数据修改为 设置值

    $set  : 
        修改一个值 , set 同时有增加一个域的作用。
        db.class.update({name:"阿花"},{$set:{age:21,sex:"m"}},true,true)
            修改阿花,年龄21 性别 m

    $unset :
        删除一个域 , hobby 后面的可以随便写,习惯写 1  
        db.class.update({name:"阿花"},{$unset:{hobby:[这里随便写]}},true,true)

    $rename 
        修改一个域的 名称
        db.class.update({},{$rename:{sex:"gender"}},true,true)
            修改所有域中 sex域名 为 gender域名 , 注意判断条件不写代表修改所有的域


    $inc :
        对某个域的值进行 加减修改。
        db.class.updata({name:"宝强"},{$inc:{age:5}},true,true)
            对 name 为宝强的文档 的age 加 +5 操作 (正数加,负数减)
    
    $mul : 
        对某个域的值进行 乘法修改
        db.class.update({name:"宝强"},{$mul:{age:2}},true,true)
            将name 为宝强的 age 乘以 2

    $min : 
        即 : 实际值 与 给定值进行比较,如果小不管,如果大则赋值为 给定值
        设定最小值,如果query 匹配到的文档指定域值小于 min 设定不做修改
        如果大于指定的 min 值,则改为 min 值
        db.class.update({name:"宝强"},{$min:{age:20}},true,true)
            如果 宝强的 age 小于20 则不变,大于 20 则改为 20

    $max :
        实际值 与 给定值进行比较,如果 大于 max设定值则不变,
        如果 实际值 小于 max 给定值 则修改为 设定值。
        db.class.update({},{$max:{age:17}},true,true)
            将所有文档 age 小于 17 的修改为 17

组合使用
db.class.update({name:“阿花”},{ i n c : a g e : 3 , inc:{age:3}, inc:age:3,set:{sex:“w”}},true,true)
将 name 为阿花的成员,age +3,sex 修改为"w"


数组修改器
修改对象为 值为 数组的 文档
KaTeX parse error: Expected '}', got 'EOF' at end of input: …e({name:"阿花"},{push:{hobby:“唱歌”}},true,true)
姓名为 阿花 的 hobby 中增加 一项 唱歌

$pushAll
    项数组中 增加多项
    db.class.update({name:"Lily"},{$pushAll:{hobby:["python","html"]}},true,true)
        姓名为 Lily 的 hobby 增加两项 python、html

$each
    db.class.update({name:"Tom"},{$push:{hobby:{$each:["c++","c#"]}}},true,true)
        向姓名为 Tom 的hobby 中增加两项 c++ c#

$pull 
    从数组中删除一个元素
    db.class.update({name:"小谭"},{$pull:{hobby:"开玩笑"},true,true)
        从姓名为 小谭的 hobby 数组中删除一项 开玩笑

$pullAll
    从数组中删除 多个元素
    db.class.update({name:"Tom"},{$pullAll:{hobby:["开玩笑","假打"]}},true,true)
        从姓名为 Tom 的 hobby 中删除 开玩笑 和 假打 两个元素

#pop 
    从数组的 两端 弹出元素
    db.class.update({name:"Tom"},{$pop:{hobby:1}},true,true)
        从姓名为 Tom 的hobby数组中弹出最后一项元素(1为升序顺数,-1为降序倒数)
    
$addToSet
    向数组中添加一个元素,但该元素不能和原有元素重复(无重复的添加)
    db.class.update({name:"小娇"},{$addToSet:{hpbby:"无理取闹"}},true,true)
        如果 小娇 的hobby 中已有"无理取闹"则无法添加,(但是使用push 是可以的)

作业 :
1. 对mongo 增删改查语句进行梳理
2. 自定义数据库做查找练习


day2 回顾
数据查找操作: find(query,field)
find : 查找所有符合筛选条件的文档
findOne : 查找一个符合筛选条件的文档
** query : l t , lt , lt,gt , $eq , $gte , l t e , lte , lte,neq ,$in , $nin
$and , $or , $not , $nor
$exists , $type
field : 查找的字段显示与否的选择项

    查找函数 :
        limit(n),skip(n),sort(age:1),count(),pretty(格式化显示)

    数据的删除操作: remove(query,justOne)
            query : 定位需要删除的数据
            justOne : true 只删除第一条匹配到的数据
                        false 删除所有匹配到的数据

    更新数据: 
            update(query,update,upsert,multi)
            query : 更新条件
            update : 更新内容
            upsert : 更新插入,true 表示允许更新插入
                               false 表示允许更新,但不插入

    修改器 :
        $set : 修改一个数据的值,也可以加一个新的域值
        $unset : 删除一个域
        $reneme : 修改一个域 的名称

null
1. 表示某个域如果没有值却存在 则可以设置为null
2. 表示某个域不存在也能够进行匹配
db.class.find({country:null},{}) # 查找country 域为null 的文档


文档类型数据
db.book.insert([{Python:{title:“Python Web”,price:46,sheek:256}},
{Html:{title:“Html5 + Css5”,price:58,sheek:369}}])
在 book 文档中插入 Python 和 Html 域,内部文档嵌套着内部文档

* 注意,外部文档的域引用 内部文档的域 通过"."的方法逐层引用(内部文档中 还嵌套着内部文档),
    在使用时需要加引号。
db.book.find({"Python.title":"Python Web"},{_id:0})
    查找内部文档 title 值为Python Web 的文档

文档类型数据修改
db.book.update({“Python.title”:“Python Web”},{$set:{“Python.price”:40}},true,true)
对内部文档 price 的值修改为 40
内部文档删除 同理 $unset:{""}

数组数据的下标引用
db.class.find({“hobby.0”:“song”},{})
对 class 中 hobby 第一项为 ‘song’ 进行查找

文档有序性的体现
查询结果通过 [] 的方式既可以取得查询结果中的第几项
db.class.find()[0]
返回查询结果的 首个选项


索引 (内部所以结构 :B+树 , B-树 ,红黑树)索引由数据库软件设定的
指的是指定键值 及所在文档中的存储位置对照关系清单,使用所用可以方便我们快速查找,
减少遍历次数,提高效率(让查找速度更快)

创建单个索引: 根据函数 ensureIndex() 创建索引
    ensureIndex()
        功能 : 创建索引
        参数  :  提供索引的类别选项

创建复合索引 (同时根据多个域 创建索引)
    db.class.ensureIndex({name:1,age:1})


* 1 表示为该域创建正向索引, -1 表示逆向索引

例如:
根据 name 域创建正向索引:
db.class.ensureIndex({“name”:1})

 查看当前集合的索引
    db.class.getIndexes()

删除索引
db.class.dropIndex({name:1})
功能 : 删除索引
注意 : _id 索引是不可以被删除的, 对于复合索引时 怎么创建的 语句 就根据相应的顺序怎么删除

例 : db.class.dropIndex({name:1,age:1})
    db.class.dropIndexes()    # 删除指定集合中 除_id外的所有索引 注意为 Index 后面加 es

explain() 函数
功能 : 显示 详细的查找操作信息,显示查找是使用什么所以进行查询 inputStage : indexName : “name”
表示使用了索引. 显示使用索引的详细信息
db.class.find({name:“小谭”},{}).explain()


索引类型(索引种类)
1. 数组索引 : 指的是,如果对某个数组域创建索引,则对数组中的每个值均创建了索引.通过数组中单个值进行查询也会提高效率.
例 : 
db.class.ensureIndex({hobby:1}) 创建索引 
db.class.find({hobby:“足球”},{}).explain() 中的 indexName: hobby_1

2.子文档索引 : 
    某个域值为文档,对其子文档创建索引,则可加快 通过子文档进行查找的查找速度
    db.book.ensureIndex({"Python.price":1})
    db.book.find({"Python.price":36},{})


3.唯一索引
    唯一索引创建时 希望创建索引的域有不同的值,也可以通过这个方法来限制域的值.
    db.class.ensureIndex({name:1},{unique:true})   创建 name 为唯一索引

    创建索引时 指定域的值不能有重复,创建后插入与不允许 重复的值插入

4. 覆盖索引
    查找时,只获取索引项的内容,而不去连接其他文档内容,这样从索引表就可以得到查询结果,提高了查询效率.
    db.class.find({name:"包强"},{_id:0,name:1})
        索引为 name 查找想也为 name

5. 稀疏索引(间隙索引)
    即 指针对有指定域的文档 创建索引表,没有该域的文档 不插入到索引表中.
    db.class.ensureIndex({age:1},{sparse:true})   对 age 创建稀疏索引,既没有该域不进行索引

6.文本索引
    使用文本索引可以快速进行文本检索,这在 较长的字符串 搜索中比较有用.
    db.class.ensureIndex({msg:"text",description:"text"})
    通过单词进行索搜索
    db.class.find({$text:{$search:"old   beautiful'}},{})  # 多个单词 用空格分隔开,如果有其中任意一个单词就会被搜索
    搜索包含空格的语句,需要家转意字符
    db.class0.find({$text:{$search:"\"This is\" old "}})
        表示搜索两个,其中一个为"This is" 和 old
    搜索不包含某个单词
    db.class0.find({$text:{$search:"city -big"}},{})
        表示搜索包含 city 不包含 big 的内容
    
    删除文本索引
        通过 db.class.getIndexes() 查看索引名称 indexName
        通过 db.class.dropIndex('msg_text_description_text') 删除索引

索引约束
1. 影响插入 删除 修改数据的效率.当时据发生修改时,索引必须同步更新
当数据库需要大量的查找时,使用索引可以节省较多时间 
2.索引也占有一定的空间,所以当数据量比较小时不适宜创建索引
索引为单独创建的 索引表 来链接 主数据库,所以索引会占用存储空间

综上 :并不是所有情况下都适合创建索引或者创建大量的索引

固定集合
mongodb 中可以创建大小固定的集合,称之为固定集合.
固定集合 性能出色 且适用于很多场景.
比如 : 日志处理,零时缓存
特点 : 插入数据快, 顺序查询速度快, 因为存储结构相对紧密
 能够淘汰早期的数据(例如循环存储30天的日志,超过时间自动清除)

创建固定集合
db.createCollection(collection_name,{capped:trud,size:1000,max:1000})
 创建集合时,添加第二个参数
 size : 表示设置的固定集合的大小,单位kb
  max : 表示固定集合中 最多存放多少条文档 

示例: capped : 翻译为 加盖的,即设置上限的
    db.createCollection("log",{capped:true,size:1000,max:3})
        解析:创建名为 log 的固定集合,大小为1000kb,最多存储3条记录

聚合
对数据文档进行整理统计(查找的升级版本).相当与MySQL 数据库中的 group by 分组.
db.collection_name.aggregate({聚合条件})
功能 :聚合函数,配合 聚合条件 进行数据整理
聚合操作符
$group 作用:分组,按照什么分组由 具体的分组操作符而定


  分组操作符
  $sum : 求和
    db.class.aggregate({$group:{_id:"$sex",num:{$sum:"$age"}}})
    aggregate : 表示聚合统计
    $group : 分组
    _id:"$sex" : 按照 sex 域分组,必须用引号引起来,因为表示一个参数
    num : 统计结果的 新域名
    $sum:1 : 统计对应 sex 每个值的个数
    $sum:"$age" : 求所有 sex 对应的年龄之和,注意 $age 为值需要加引号

 $avg  : 求平均数
    db.class.aggregate({$group:{_id:"sex",average:{$avg:"$age"}}})
        求 每个性别的 年龄平均数
    
$max : 求每个组的最大值
    db.class.aggregate({$group:{_id:"$sex",num:{$max:"$age"}}})
        求每个性别的 年龄最大值

$min : 求每个集合的最小值
    db.class.aggregate({$group:{_id:"$sex",num:{$min:"$age"}}})
        求每个性别的 年龄最小值

$first : 求地一个文档的指定值
    db.class.aggregate({$group:{_id:"$sex",num:{$first:"$age"}}})
        求每个性别的 年龄 第一个值

$last : 最后一个文档的指定值
    db.class.aggregate({$group:{_id:"$sex",num:{$max:"$age"}}})
        求每个性别的 年龄 最后一个值

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ass.aggregate({project:{_id:0,name:1,age:1}})
用法 同 find({},{}) 的第二个参数
db.class.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …t:{_id:0,Name:"name",Age:"$age"}})
可以改变显示的域名, 但是数据库为改变,仅仅显示改变了


KaTeX parse error: Expected '}', got 'EOF' at end of input: …ass.aggregate({match:{age:{$lt:20}}})
过滤年龄小于 20 的

l i m i t 显 示 前 几 条 数 据 , 值 为 一 个 正 整 数 d b . c l a s s . a g g r e g a t e ( limit 显示前几条数据,值为一个正整数 db.class.aggregate( limit,db.class.aggregate(limit:3)
显示前 3 条数据

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ass.aggregate({skip:2})
跳过前 2 条数据,显示后面的数据

KaTeX parse error: Expected '}', got 'EOF' at end of input: …ass.aggregate({sort:{age:1}})
按照年龄升序排序


聚合管道 (常用的使用方法)
类似与车间流水线,前一个聚合操作的结果 给 后一个聚合操作执行.
格式 : 将多个聚合操作放到一个 中括号 [ ] 中
示例:
match结果->sort–> project显示
db.class.aggregate([{KaTeX parse error: Expected 'EOF', got '}' at position 16: match:{sex:"m"}}̲,{sort:{age:1}},{KaTeX parse error: Expected 'EOF', got '}' at position 16: project:"_id:0"}̲]) db.l…match:{age:{KaTeX parse error: Expected 'EOF', got '}' at position 6: gt:10}̲}},{sort:{age:1}},{$project:{_id:0}}])


第四天回顾
updata({},{},false,false) 修改器为 第二个参数
修改器有:
$set 修改一个数据或者添加一个域
$unset 删除一个域
$rename 重命名一个域名
$inc 做加减运算
$mul 做乘法运算
$min 最大值限定
$max 最小值限定
$push 向数组中增加一个值
$pushAll 向数组增加多个值
$each
$pull
$pullAll
$addToset
$pop

索引
    创建索引 :ensureIndex(name:1)
    删除单个索引 : dropIndex(name:1)
    删除全部索引 :dropIndexes()
    查看查找的详细信息: explain()
        唯一索引
        复合索引{age:1,name:1}
        数组索引
        单一索引
        稀疏索引
        覆盖索引
        文本索引

固定集合:
    创建集合函数: db.createCollection("集合名称",{capped:true,size:1000,max:1000})

聚合
    aggregate()  更高级的查找,有更丰富的过滤
    $group  : 分组  $sum $min $max $avg $first $last
    $match : 过滤
    $project : 显示
    $limit : 显示项数
    $skip : 跳过
    $sort : 排序

聚合管道
    db.class.aggregate([{聚合1},{聚合2},{聚合3})

大文件存储 : GridFS
文件的数据库存储
1.在数据库中以字符串的方式存储 文件在本地的路径.
(节省数据库空间,但是数据库或文件位置发生变化时 无法找到文件)
2.将文件以二进制数据的方式存储在数据库中
(当存储文件大时空间使用大且提取困难,文件和数据库绑定不容易丢失)

GridFS : 是mongoDB 当中存储大文件的一种方案,mongoDB中认为超过16M的文件为大文件.
方案为 : 将文件存储在mongoDB数据库中,通过 两个集合 共同完成该文件的存储.
第一个集合 fs.files : 存储文件的相关信息,比如文件名filename,文件类型content_type等
第二个集合 fs.chunks : 实际存储文件内容,以二进制方式分块存储,将大文件分成多个小块,每个小块占一条文档.
文件进行 多块二进制分存,每块为一条文档.

使用实例:
mongofiles -d database_name put file_name
mongofiles : 命令
database_name : 文件要存储的数据库,如果不存在则自动创建
file_name : 要存储的文件
终端上输入: mongofiles -d grid put abc.mp3
-d grid : 选择数据库,如果数据库不存在会自动创建一个数据库
put : 向数据库中存入数据
abc.mp3 : 运行命令之前,向mongodb 文件夹中复制的文件的文件名(要存储的文件)
 不在当前文件夹下,写相应文件存储路径也可以

查看文件信息
db.fs.files.find()
复制要查看文件的 _id 对应的 Object_id 值
查看文件具体内容
db.fs.chunks.find({files_id:ObjectId(“5cab37e069d72e22fc723caf”)},{})

fs.chunks 的域 _id
files_id : 值为对应文件在 fs.files 集合中的文档的 _id 值
n : 分块信息
data : 具体文件二进制内容

该种存储方法优缺点
优点 : 存储方便,没有个数限制,方便数据库的移植或迁移
缺点 : 读写效率低,虽然分块存储的,但只能整体修改不能分块更新.


游标 
对数据库操作结果的集合概念,即执行结果的一个对象,称之为游标.
相当与 列表(find)和迭代器游标类是与迭代器 要用一个返回一个.

为什么使用游标
    1.防止网络拥塞,造成数据传输慢
    2.避免用户解析带来的体验差,可以进行后端解析.
    当用户数据量比较大的时候 比较适合使用游标.

使用方法:
    var cursor = db.class.find()   创建游标 cursor 变量
    cursor.hasNext() 查看是否有下一条文档,有则返回true
    cursor.next()  类似 python 迭代器,用以获取下一条文档内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值