文档型非关系数据库MongoDB

数据库基础概念

  1. 数据:能够输入到计算机中并被识别处理的信息集合
  2. 数据结构:研究一个数据集合中,数据元素关系
  3. 数据库:按照数据结构,存储管理数据的仓库。数据仓库是在数据库管理系统管理控制下在一定介质中
    创建的
  4. 数据库管理系统:数据库管理软件,用于建立维护操作数据库
  5. 数据库系统:由数据库和数据库管理系统等构成的数据库开发工具集合。

关系型数据库 & 非关系型数据库的特点

关系型数据库

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

1: 常见关系型数据库:Oracle DB2 SQLServer MySQL SQLite
2:优缺点
优点:逻辑清晰,容易理解,结构类似常见表格

​ 使用 SQL语句,技术成熟,使用方便

​ 关系型数据库比较成熟,可以使用一些复杂的操作

缺点:每次操作都需要专门的 sql解析

​ 关系型数据库结构严格,内部加锁

​ 在应对海量数据并发处理时读写速度差

非关系型数据库(NoSql–>not only sql)

1: 常见的非关系型数据库

​ 不是采用关系模型构建的数据库
​ 键值型 : Redis
​ 列存储 : HBase
​ 文档型 : MongoDB
​ 图形 : Graph

2:优缺点
优点 :读写速度快,更好的针对并发处理

​ 使用灵活,容易扩展

缺点 :没有 sql那样统一成熟的语句

​ 技术成熟度较差,缺少一些复杂操作

3:应用场景

  1. 对数据格式要求不严格,比较灵活
  2. 对数据处理速度,特别是海量数据的并发处理速度要求比较高
  3. 特定场景:需要灵活扩展,需要作为缓存

MongoDB数据库

mongodb特点

​ 非关系型数据库,是属于文档型数据库

​ 开源数据库,使用广泛

​ 由 c++ 编写的数据库管理系统

​ 支持丰富的存储类型和数据操作

​ 提供了丰富的编程语言接口

​ 方便扩展和部署

MongoDB 安装

Linux : sudo apt-get install mongodbMac OS:  brew install mongodbWindows: www.mongodb.com -->Try free -->server 下载安装

Linux 安装目录

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

进入 mongodb交互界面

名称 : mongodb shell
命令 : mongo
退出 : quit() ctrl-c

mongod 设置 mongodb的基本信息

mongod -h                查看帮助
mongod --dbpath [dir]   设置数据库存储位置
mongod --port [port]    设置数据库端口
mongodb默认端口           27017

MongodDB 数据库数据结构

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

ID NAME AGE
1 Lily 17
2 Lucy 18
{"_id":1,"NAME":'Lily',"AGE" :17
},
{"_id":2,"NAME":'Lucy',"AGE" :18
}

2:基本概念对比

mysql mongodb 含义
database database 数据库
table collection 表 / 集合
column field 字段 / 域
row document 记录 / 文档
index index 索引

数据库操作

创建数据库: use [database]

e.g. 创建一个叫 stu的数据库 use stu
  • use实际是选择使用哪个数据库,当这个数据库不存在则自动建立
  • use 创建数据库并不会立即建立起来,而是当真正插入数据时才会建立

查看数据库 : show dbs

数据库命名规则:

  • 使用 utf-8字符串
  • 不能含有 空格 . / \ ‘\0’ 字符
  • 不能超过 64字节
  • 不要和系统库重名

全局变量 db : 代表当前正在使用的数据库

  • 不选择任何数据库时 db = test

数据库的删除: db.dropDatabase()

数据库的备份和恢复命名
备份命令:

mongodump -h [host] -d [db] -o [path]
e.g. 将本机stu 数据库备份在当前目录下mongodump -h 127.0.0.1 -d stu -o .

​ 恢复命令:

mongorestore -h [host:port] -d [db] [bak]
e.g. 将stu备份恢复到本机student数据库中mongorestore -h 127.0.0.1:27017 -d student stu

数据库运行监控

查看数据库的运行状态: mongostat
insert query update delete:每秒增查改删次数
查看数据库集合读写时长: mongotop:功能:得到每个集合在一秒内的读写时间

集合操作

创建集合

db.createCollection(collectionName)
e.g. 创建名为 class1的集合
db.createCollection('class1')
db.colletion.insert(...)
原理:插入数据时如果集合不存在则自动创建

查看集合:

show collections
show tables

集合命名规则

  • 使用 utf-8 字符
  • 不能含有 ‘\0’
  • 不要以 system. 开头,这是系统集合默认开头
  • 不要和关键字重名

删除集合

db.collection.drop()
e.g. 删除 class集合
db.class.drop()

集合重命名

db.collection.renameCollection(newName)
e.g. 将 class重命名为 class0
db.class.renameCollection('class0')

文档操作

什么是文档

​ 文档是 mongodb数据库中基本的数据组织单元

​ 文档由键值对构成,每个键值对表达一个数据项

​ mongodb文档数据 bson类型数据

文档键值对特点:

​ 无序的

​ 通过键取其值

​ 不能重复

​ 键是 utf-8字符串,不能有’\0’字符

​ 值为 bson支持数据类型,即存储的数据

数据类型:

​ 整型 int : 整数
​ 浮点型 double : 小数
​ 布尔 boolean : true false
​ 字符串 string : utf-8字符串
​ ObjectId : id 对象 自动生成的不重复值

​ 注意:mongodb插入文档时,每个文档都要有一个_id域,可以自己指定一个不重复的值,也可以由系统自动生成

集合中文档设计

  1. 一个集合中的文档可以有不同的域,域的个数也可以不一致。
  2. 集合中的文档层次不宜嵌套过多,如果层次过多时应考虑分为多个集合
  3. 在一个集合中的文档应该尽量表达相同类型的数据内容

数据操作

插入文档

db.collection.insertOne(doc)
功能: 插入一条文档
参数:要插入的文档
e.g. 插入一条文档
db.class0.insertOne({'name':'Lucy','age':18,'sex':'w'})
* 操作数据时,键可以不加引号
* 可以自己设置_id值,但是不能重复
db.collection.insertMany([{},{}...])
功能: 插入多条文档
参数: 数组中为多个文档
e.g. 同时插入多个文档
db.class1.insertMany([{name:'百合',age:33,sex:'w'},{name:'蓉',age:28,sex:'w'},
{name:'小许',age:46,sex:'m'}])数组:使用 [] 表示的一组数据有序集合特点 : 有序,使用序列号取值db.collection.insert()
功能: 插入一条或多条文档
参数:同 insertOne + insertMany
db.collection.save()
功能:插入一条或多条文档
参数:同 insert
* 使用 save 如果_id重复会替换掉原有文档

查找操作

mysql select ... from table where ...
mongo db.collection.find(query,field)
db.collection.find(query,field)功能: 查找所有符合条件的文档参数:query 查找条件field 要查找的域返回: 返回所有查找到的文档
db.collection.find() ==> select * from table
query : 是一个 键值对文档{},空则表示所有以键值对表示筛选条件,往往配合查找操作符完成
* field : 是一个键值对文档{}, field:0表示不查找这个与,field:1表示查找这个域。_id 域如果不想查找 _id:0其他域设置要么全为 0 要么全为 1
e.g. 查找所有年龄 18的文档,只查找 name,age域
db.class0.find({age:18},{_id:0,name:1,age:1})db.collection.findOne(query,field)功能: 查找第一个复合条件的文档参数: 同find返回:返回查找到的文档  e.g.  查找第一个性别为男的文档db.class0.findOne({sex:'m'},{_id:0})

query操作符使用

操作符:mongodb中使用符号注明的一个有特殊意义的字符串,用以表达丰富的含义,比如:符号注明的一个有特殊意义的字符串,用以表达丰富的含义,比如:符号注明的一个有特殊意义的字符串,用以表达丰富的含义,比如:lt 表示小于

比较操作符
【1】 $eq  等于  =
e.g.  年龄等于17 db.class0.find({age:{$eq:17}},{_id:0})【2】 $lt  小于  <
e.g. 字符串可以比较大小db.class0.find({name:{$lt:'Tom'}},{_id:0})【3】 $gt  大于  >
e.g. 查找一个区间范围db.class0.find({age:{$gt:17,$lt:20}},{_id:0})【4】 $lte  小于等于  <=【5】 $gte  大于等于  >=【6】 $ne   不等于    !=【7】 $in   包含
e.g. 查找年龄在数组范围的db.class0.find({age:{$in:[17,19,21]}},{_id:0})【8】 $nin  不包含
e.g. 查找年龄不在数组范围的db.class0.find({age:{$nin:[17,19,21]}},{_id:0})
逻辑操作符
【1】 $and   逻辑与
e.g.  查找年龄小于19 并且性别为w的db.class0.find({$and:[{age:{$lt:19}},{sex:{$ne:'w'}}]},{_id:0})
* query中的多个条件本身也表示并且关系【2】 $or  逻辑或
e.g.  查找年龄大于18或者性别为wdb.class0.find({$or:[{age:{$gt:18}},{sex:'w'}]},{_id:0})【3】 $not  逻辑非
e.g. 查找年龄不大于18的db.class0.find({age:{$not:{$gt:18}}},{_id:0})【4】 $nor 既不也不(多个条件均为假则结果为真)
e.g.  年龄不大于18 性别不为 mdb.class0.find({$nor:[{age:{$gt:18}},{sex:'m'}]},{_id:0})【5】 混合条件语句
e.g.  年龄大于等于19或者小于18  并且 性别为 wdb.class0.find({$and:[{$or:[{age:{$gte:19}},{age:{$lt:18}}]},{sex:'w'}]},{_id:0})e.g. (年龄大于等于17的男生) 或者  (姓名叫 Abby 或者Emma)db.class0.find({$or:[{age:{$gte:17},sex:'m'},{name:{$in:['Abby','Emma']}}]},{_id:0})
数组操作符
【1】 查找数组中包含元素
e.g.  查找score数组中元素包含大于90的文档db.class2.find({score:{$gt:90}},{_id:0})【2】 $all  查找数组中同时包含多项
e.g. 查找数组中同时包含87,89的文档db.class2.find({score:{$all:[87,89]}},{_id:0})【3】 $size 根据数组的元素个数查找
e.g.  查找数组中包含3个元素的文档db.class2.find({score:{$size:3}},{_id:0})【4】 $slice 用于field参数,表示查找数组哪些项
e.g.  查找数组中的前两项db.class2.find({},{_id:0,score:{$slice:2}})
e.g.  跳过数组第一项,查看后面两项db.class2.find({},{_id:0,score:{$slice:[1,2]}})【5】 通过数组索引进行查找
e.g.  查找数组第二项大于80的文档db.class2.find({'score.1':{$gt:80}},{_id:0})* 通过score.1表示第二项,需要加引号表达
其他操作符
【1】 $exists  判断一个域是否存在
e.g.  查找有sex域的文档db.class0.find({sex:{$exists:true}},{_id:0})【2】 $mod   根据除数余数筛选
e.g. 查找age 除以 2 余数为1的文档db.class0.find({age:{$mod:[2,1]}},{_id:0})【3】 $type  根据数据类型筛选
e.g.  查找 age域值为 字符串类型的db.class2.find({age:{$type:2}},{_id:0})* 数据类型与数字对应查看type表

数据操作函数

1. db.collection.distinct(field)功能: 获取集合中某个域的值范围参数: 域名返回值: 取值的范围 数组
e.g. 查找class0 age域有哪些值db.class0.distinct('age')2. pretty() 功能: 将find结果格式化显示3. limit(n)功能: 显示查询结果的前n条
e.g.  显示查询结果前3条db.class0.find({},{_id:0}).limit(3)4. skip(n)功能 :跳过前n条显示后面的文档
e.g. 跳过前5个文档,显示后面内容db.class0.find({},{_id:0}).skip(5)5. count()功能: 统计查询结果数量
e.g.  统计年龄大于18的文档个数db.class0.find({age:{$gt:18}},{_id:0}).count()6. sort({field:1/-1})功能: 对查找结果排序参数: field 表示排序的域,1升序  -1降序
e.g.  年龄为数字的域按照降序排序db.class0.find({age:{$type:1}},{_id:0}).sort({age:-1})
e.g.  复合排序(第一排序项相同的时候按照第二项排序)db.class0.find({age:{$type:1}},{_id:0}).sort({age:1,name:1})7. 函数连续调用如果上一个函数返回的仍是一个文档集合则可以继续调用下一个操作函数
e.g.  查找年龄最大的三位同学db.class0.find({age:{$type:1}},{_id:0}).sort({age:-1}).limit(3)8.  通过序列号直接获取文档集合中某一个
e.g.  获取文档集合第二项db.class0.find({},{_id:0}).sort({age:1})[1]
示例:使用grade
1. 查看班级中所有人信息find()2. 查看班级中年龄8岁的人员信息find({age:8})3. 查看年龄大于10岁的学生信息find({age:{$gt:10}})4. 查看年龄8-12之间的学生信息find({age:{$gte:8,$lte:12}})find({$and:[{age:{$gte:8}},{age:{$lte:12}}]})5. 查看年龄为9岁且喜欢画画的女生find({age:9,sex:'w',hobby:'draw'})6. 查看年龄小于8岁或者大于12岁的同学find({$or:[{age:{$lt:8}},{age:{$gt:12}}]})7. 查看年龄9岁或者11岁的学生find({age:{$in:[9,11]}})8. 查看有两项兴趣爱好的学生find({hobby:{$size:2}})9. 查找喜欢计算机的同学find({hobby:'computer'})10. 查找既喜欢画画又喜欢跳舞的同学find({hobby:{$all:['draw','dance']}})11. 统计兴趣爱好有3项的学生人数find({hobby:{$size:3}).count()12. 找到班级中年龄第二大的同学find().sort({age:-1})[1]find().sort({age:-1}).skip(1).limit(1)13. 找到班级中年龄最小的三位女生find({sex:'w'}).sort({age:1}).limit(3)

修改操作

格式对比
mysql:update  table  set ... where ...mongo: db.collection.updateOne(query,update,upsert)
修改函数
updateOne(query,update,upsert)功能: 修改第一个符合条件文档参数: query  筛选条件  同 find update 要修改的数据,需要同修改操作符一起使用upsert 如果query没有筛选到文档是否插入新的文档update  键值对文档,表达将数据修改为什么样子e.g. 将tom年龄修改为16db.class0.updateOne({name:'Tom'},{$set:{age:16}})upsert 如果设置为true,此时query没有筛选到文档会根据前两个参数插入新的文档
e.g.  如果没有Levi则插入新的文档db.class0.updateOne({name:'Levi'},{$set:{age:21}},{upsert:true})updateMany(query,update,upsert):功能: 修改所有符合条件的文档参数: 同  updateOne
e.g.  修改age域为字符串的年龄改为18db.class0.updateMany({age:{$type:2}},{$set:{age:18}})
update(query,update,upsert,multi)功能: 修改文档参数:query  update 用法同 updateOneupsert  upsert=true 表示查找不到文档则插入新的文档multi   默认只修改一个文档 ,multi=true:表示修改所有符合条件文档
e.g. 修改jack年龄16,如果不存在则插入,如果存在多个则全部修改db.class0.update({name:'Jack'},{$set:{age:16}},true,true)findOneAndUpdate(query,update)功能: 查找到一个文档并修改参数: query 查找条件update  修改数据返回值 : 修改前的文档
e.g.  查找到Emma 并修改其年龄为19db.class0.findOneAndUpdate({name:'Emma'},{$set:{age:19}})findOneAndReplace(query,doc)功能: 查找一个文档并替换之参数:query  查找条件doc  新的文档返回: 返回原文档
e.g.  查找lily文档并替换之db.class0.findOneAndReplace({name:'Lily'},{name:'Jame',age:17,sex:'m'})
修改操作符(修改器)
【1】 $set: 修改一个域的值或者增加一个域
e.g. 修改Levi sex域为'm',如果没有这个域会自动增添db.class0.updateOne({sex:{$exists:false}},{$set:{sex:'m'}})
* 一个修改器可以同时修改多项【2】 $unset: 删除一个域
e.g. 删除lucy的sex域db.class0.updateOne({name:'Lucy'},{$unset:{sex:''}})【3】 $rename : 给域重命名
e.g.  给sex域 重命名为genderdb.class0.updateMany({},{$rename:{sex:'gender'}})【4】 $setOnInsert : 如果使用update*执行了插入文档操作,则作为插入的内容
e.g.  如果执行了插入文档则setOnInsert内容也会插入db.class0.updateOne({name:'Daivl'},{$set:{age:18},$setOnInsert:{gender:'m'}},{upsert:true})
* update参数可以使用多个修改器【5】  $inc :  加法修改器
e.g.  所有人年龄加1db.class1.updateMany({},{$inc:{age:1}})【6】 $mul  :  乘法修改器
e.g. 所有人年龄乘以0.5db.class1.updateMany({},{$mul:{age:0.5}})
* $inc  $mul 操作数可以是整数 小数 正数 负数   【7】 $max :  修改某个域的值,如果小于指定值则改为指定值,大于则不变
e.g.  如果age域小于30改为30,大于30则不变db.class1.updateMany({sex:'w'},{$max:{age:30}})【8】 $min :修改某个域的值,如果大于指定值则改为指定值,小于则不变
e.g.  将age大于30的文档,如果age大于40改为40db.class1.updateMany({age:{$gt:30}},{$min:{age:40}})
数组修改器
1. $push  向数组中添加一项
e.g.  给小红score数组增加一个元素10db.class2.updateOne({name:'小红'},{$push:{score:10}})2. $pushAll  向数组中添加多项
e.g.  给小明score数组中增加多个元素db.class2.updateOne({name:'小明'},{$pushAll:{score:[10,5]}})3. $pull : 从数组中删除某个值
e.g.  删除小刚score数组中的90db.class2.updateOne({name:'小刚'},{$pull:{score:90}})4. $pullAll : 同时删除数组中多个值
e.g.  删除小明score数组多个值db.class2.updateOne({name:'小明'},{$pullAll:{score:[69,5]}})5. $pop : 弹出数组中一项
e.g.   弹出数组中最后一项 (1表示最后一项,-1表示第一项)db.class2.updateOne({name:'小红'},{$pop:{score:1}})6. $addToSet : 向数组中添加一项,但是不能和已有的数值重复
e.g.   向score增加80,但是不能和已有的重复db.class2.updateOne({name:'小刚'},{$addToSet:{score:80}})7. $each : 对多个值逐一操作
e.g.    对90  10 都执行push操作db.class2.updateOne({name:'小红'},{$push:{score:{$each:[90,10]}}})8. $position : 指定数据插入位置 配合$each
e.g.   将90 插入到 索引1位置db.class2.updateOne({name:'小刚'},{$push:{score:{$each:[90],$position:1}}})9. $sort :  给数组排序  配合$each使用
e.g.    将小红score数组按照降序排序 (-1降序,1升序)db.class2.updateOne({name:'小红'},{$push:{score:{$each:[],$sort:-1}}})
示例:使用grade
1. 将小红年龄修改为8岁,兴趣爱好改为跳舞画画updateOne({name:'小红'},{$set:{age:8,hobby:['dance','draw']}})2. 小明多了一个兴趣爱好 唱歌updateOne({name:'小明'},{$push:{hobby:'sing'}})3. 小王兴趣爱好多个吹牛,打篮球updateOne({name:'小王'},{$push:{hobby:['吹牛','basketball']}})4. 小李兴趣增加跑步,唱歌,但是确保不和以前的重复updateOne({name:'小李'},{$addToSet:{hobby:{$each:['running','sing']}}})5. 班级所有同学年龄增加1updataMany({},{$inc:{age:1}})6. 删除小明的sex属性updateOne({name:'小明'},{$unset:{sex:''}})7. 小李第一个兴趣爱好不要了updateOne({name:'小明'},{$pop:{hobby:-1}})8. 小刚不喜欢计算机和画画了updateOne({name:'小明'},{$pullAll:{hobby:['draw','computer']}})

删除操作

格式对比
mysql : delete  from  table  where ... mongo : db.collection.deleteOne(query)
删除函数
1. db.collection.deleteOne(query)功能: 删除第一个符合条件文档参数: 筛选条件
e.g.  删除第一个不存在 gender域的文档db.class0.deleteOne({gender:{$exists:false}})2. db.collection.deleteMany(query)功能: 删除所有符合条件文档参数: 筛选条件
e.g.  删除所有小于18岁的文档db.class0.deleteMany({age:{$lt:18}})*  删除一个集合中所有文档db.class1.deleteMany({})3. db.collection.remove(query,justOne)功能: 删除文档参数: query  筛选条件justOne=>false 删除所有符合条件文档(默认)justOne=>true  只删除一个符合条件文档
e.g.  删除第一个性别为m的文档db.class0.remove({gender:'m'},true)4. db.collection.findOneAndDelete(query)功能: 查找一个文档并删除之参数: 查找条件返回: 查找到的文档
e.g. 查找Levi并删除db.class0.findOneAndDelete({name:'Levi'})
示例:使用grade
1. 删除所有年龄小于8岁或大于12岁的同学deleteMany({$or:[{age:{$gt:12}},{age:{$lt:8}}]})2. 删除兴趣爱好中没画画或跳舞的同学 deleteMany({hobby:{$nin:['draw','dance']}})

MongoDB的一些数据类型

时间类型
【1】 获取当前时间
* new  Date()  自动生成当前时间
e.g: db.class1.insertOne({book:'Python入门',date:new Date()})* Date()  获取计算机当前时间生成字符串
e.g: db.class1.insertOne({book:'Python精通',date:Date()})【2】 时间函数
ISODate()功能 : 将制定时间转换为标准时间存入参数: 默认同  new  Date() 获取当前时间或者字符串制定时间"2019-01-01  08:08:08""20190101  08:08:08""20190101"
e.g.  传入制定时间db.class1.insertOne({book:'Python疯狂',date:ISODate("2019-01-01 08:08:08")})【3】 时间戳
valueOf()功能: 将标准时间转化为时间戳
e.g. 将标准时间转换为时间戳db.class1.insertOne({book:'Python涅槃',date:ISODate().valueOf()})
Null 类型
【1】 值 : null【2】 含义 : * 表示某个域的值为空
e.g.  price域的值为空db.class1.insertOne({book:'Python Web',price:null})
* 查找时表示某个域没有e.g.   查找到price域为null或者没有该域的db.class1.find({price:null},{_id:0})
内部文档(Object类型)
【1】 定义: 文档中某个域的值为内部文档,则该值为object类型数据【2】 使用方法:当使用内部文档某个域的值时,需要采用个"外部域.内部域"的方法,此时该格式需要用引号表示为字符串
e.g.  找到出版社为中国文学的db.class3.find({"intro.publication":'中国文学出版社'},{_id:0})
示例:使用grade
1. 将小红爱好的第二项变为 唱歌updateOne({name:'小红'},{$set:{'hobby.1':'sing'}})2. 给小王增加一个域,备注:{民族:'回族',习俗:'注意饮食禁忌'}updateOne({name:'小王'},{$set:{备注:{民族:'回族',习俗:'注意饮食禁忌'}}})3. 修改小王的备注域,增加一项,宗教 : '伊斯兰'updateOne({name:'小王'},{$set:{'备注.宗教':'伊斯兰'}})

索引操作

索引含义

​ 索引是建立文档所在位置的查找清单,使用索引可以方便快速查找,减少遍历次数,提高查找效率

索引约束

​ 注意:数据量很小时不需要创建索引

创建索引
【1】 db.collection.createIndex(index,option)功能: 创建索引参数:索引域和索引选项
e.g. 为name域创建索引db.class0.createIndex({name:1})* _id域会由系统自动生成索引* 1 表示正向索引,-1表示逆向索引                    【2】 db.collection.getIndexes()功能: 查看集合中索引【3】 通过第二个参数定义索引名
e.g.  创建索引名字为ageIndexdb.class0.createIndex({age:-1},{name:'ageIndex'})【4】 其他索引创建方法ensureIndex()功能: 创建索引参数: 同 createIndex()createIndexes([{},{}..])功能: 创建多个索引参数: 数组中写多个键值对
删除索引
【1】 db.collection.dropIndex(index or name)功能: 删除一个索引参数: 索引名称或者键值对
e.g.  通过名称或者键值对删除db.class0.dropIndex('name_-1')db.class0.dropIndex({age:-1})【2】 db.collection.dropIndexes()功能 : 删除所有索引* _id索引不会被删除
其他类型索引
【1】 复合索引: 根据多个域创建一个索引db.class0.createIndex({name:1,age:-1})【2】object/数组索引 : 如果对object域或者数组域创建索引则针对object或者数组中某一个元素的查询也是索引查询
e.g. 如果对intro创建了索引,则该查找也是索引查找db.class3.find({'intro.author':'曹雪芹'})【3】 唯一索引 : 要求创建索引的域不能有重复值
e.g. 对name域创建唯一索引db.class0.createIndex({name:1},{unique:true})【4】 稀疏索引 : 如果创建稀疏索引则对没有索引域的文档会忽略
e.g. 对age 创建稀疏索引db.class0.createIndex({age:1},{sparse:true,name:'Age'})

聚合操作

什么是聚合

​ 聚合是对文档进行数据整理统计,得到统计结果。

集合函数
db.collection.aggregate(aggr)功能: 执行聚合操作参数: 聚合条件,配合聚合操作符使用
聚合操作符
【1】 $group  分组聚合  需要配合统计操作符* 统计求和 : $sum
e.g. 按性别分组统计每组人数db.class0.aggregate({$group:{_id:'$gender',num:{$sum:1}}})* 求平均数 : $avg
e.g.  按性别分组求平均年龄db.class0.aggregate({$group:{_id:'$gender',num:{$avg:'$age'}}})* 求最大最小值 : $max / $min
e.g. 按性别分组求每组的最大值db.class0.aggregate({$group:{_id:'$gender',num:{$max:'$age'}}})* $first/$last   求第一项值和最后一项值【2】 $match  数据筛选 * match 值的写法同find函数中query写法
e.g. 筛选年龄大于18的文档db.class0.aggregate({$match:{age:{$gt:18}}})【4】 $limit  显示集合中前几条文档
e.g. 显示前3个文档内容db.class0.aggregate([{$limit:3}])【5】$skip  跳过前几个文档显示后面的内容
e.g. 跳过前3个文档显示后面内容db.class0.aggregate([{$skip:3},{$project:{_id:0}}])【6】 $sort  对集合文档排序
e.g. 对文档按年龄排序db.class0.aggregate([{$sort:{age:1}},{$project:{_id:0}}])
【7】 $project :  选择显示的域(值的写法同field参数)
e.g.  筛选结果不显示_iddb.class0.aggregate([{$match:{}},{$project:{_id:0,Name:'$name',Age:'$age'}}])
聚合管道
定义: 指将第一个聚合的结果交给第二个聚合操作继续执行,直到所有聚合完成。
形式: aggregate([{聚合1},{聚合2}...])
e.g. 查找年龄大于18的文档,不显示_iddb.class0.aggregate([{$match:{age:{$gt:18}}},{$project:{_id:0}}])
示例:使用grade
 1.  将所有男生按照年龄升序排序,结果不显示_idaggregate([$match:{sex:'m'},{$sort:{age:1}},{$project:{_id:0}}])2.  将所有喜欢画画的女生按照年龄排序,取年龄最小的三个,只显示姓名,年龄,爱好aggregate([{$match:{hobby:'draw',sex:'w'}},{$sort:{age:1}},{$limit:3},{$project:{_id:0,name:1,age:1,hobby:1}}])

固定集合

定义

​ 固定集合:指的是mongodb中创建固定大小的集合,称之为固定集合。

特点
1. 能够淘汰早期数据
2. 可以控制集合大小
3. 数据插入,查找速度快
使用

​ 使用 : 日志处理,临时缓存

创建
创建 : db.createCollection(collection,{capped:true,size:10000,max:20})capped:true   表示创建固定集合size :10000  固定集合大小 字节max :20    固定集合可存放文档数量
e.g. 创建固定集合log,最多存放3条文档db.createCollection('log',{capped:true,size:1000,max:3})

文件存储

文件存储数据库方式

【1】 存储路径:将本地文件所在的路径以字符串存储到数据库中。

​ 优点: 操作简单,节省数据库空间
​ 缺点:当数据库或者文件发生变化需要修改数据库

【2】 存储文件本身:将文件转换为二进制存储到数据库中。

 优点:文件绑定数据库,不容易丢失缺点: 占用数据库空间大,文件存取效率低

GridFS文件存储方案

目的:更方便的存取mongodb中大文件(>16M)

优缺点 : 对大文件的存储提取方便,但是读写效率仍然比较低,不建议用来存储小文件。

说明:
1. mongodb数据库中创建两个集合共同存储文件
2. fs.files集合中为每个文件建立一个信息文档,存储文件的基本信息
3. fs.chunks集合中每个文档建立与fs.files的关联,并将文件分块存储

存储方法:mongofiles -d  dbname  put  file
e.g.  将Postman... 存储到grid数据库中mongofiles -d grid put Postman.tar.gz 提取方法:mongofiles -d  dbname  get  file
e.g. 从数据库中获取Post...文件mongofiles -d grid  get Postman.tar.gz

mongo shell 对 JavaScript支持

* mongo shell界面中支持基本的JS代码
* 通过js处理mongo的一些数据逻辑

Python操作MongoDB

第三方模块的安装

第三方模块 : pymongo安装 : sudo  pip3 install  pymongo

操作步骤

【1】 导入模块,连接mongodb数据库
from  pymongo  import  MongoClient
conn = MongoClient('localhost',27017)【2】 选择要操作的数据库和集合
db = conn.stu   # 选择数据库
myset = db.class0  # 选择集合【3】 通过集合对象调用接口完成数据操作
数据书写转换:
文档 ----》 字典
数组 ----》 列表
布尔 ----》 python布尔
null ----》 None
操作符 ----》 字符串形式原样书写$lt               "$lt"【4】 关闭数据库连接
conn.close()

数据操作函数 (mongodb/mongo.py)

【1】 插入文档  insert_one()  插入一条文档insert_many()  插入多条文档insert()  插入一条或多条文档save()  插入文档,如果_id重复会覆盖  【2】 查找操作cursor = find(query,field)  功能:查找所有文档参数:形式同mongo中 find返回值:查找结果的游标对象cursor对象属性* 通过迭代获取每个查找文档结果* 通过调用属性方法对结果进行进一步操作next()limit()skip()count()sort([('age',1),('name',1)])注意: 1.调用limit,skip,sort时游标必须没有遍历过2. sort排序写法域mongoshell不同{age:1,name:1}->[('age',1),('name',1)]               find_one(query,field)  功能:查找一个文档参数: 同find返回值: 文档字典【3】 修改操作       update_one()  修改一个文档update_many()  修改多个文档update() 【4】 删除操作delete_one()  删除一个文档delete_many()  删除多个文档remove()【5】 复合操作     find_one_and_delete() 【6】 索引操作create_index(index,**kwargs) 功能: 创建索引参数: {name:1} --> [('name',1)] kwargs 索引选项返回值: 索引名称list_indexes()  查看索引drop_index() 删除索引drop_indexes()  删除所有索引【7】 聚合操作   cursor = aggregate([{},{}])功能: 完成聚合操作参数: 聚合管道,同mongo shell返回值: 数据结果游标

文件存储

import  bson
1. 将文件内容转换为bson二进制格式存储  content = bson.binary.Binary(bytes)功能: 将python字节串转换为bson格式参数: 要转换的字节串返回值: bson数据2. 将bson数据 插入到mongo数据库文档中

示例

"""
pymongo 模块操作示例
用于数据增删改查索引聚合方法的参考
"""
from pymongo import MongoClient
#  创建数据库连接
conn = MongoClient('localhost', 27017)
#  创建数据库对象和集合对象
db = conn.stu
myset = db.class4
#  数据操作# *********** insert **************# myset.insert_one({'name':'小明','King':' 乾隆 '})
# myset.insert_many([{'name':'小刚','King':' 康熙 '},{'name':'小强','King':' 康熙 '}])
# myset.insert({"name":'小西',"King":' 雍正 '})
# myset.insert([{"name":'小雪',"King":' 雍正 '},{"name":'小雨 ','King':" 乾隆 "}])
# myset.save({'_id':1,'name':'小米',"King":' 四爷 '})
# myset.save({'_id':1,'name':'小七',"King":' 乾隆 '})# ************* find **************#  所有的操作符加引号,作为字符串表达
cursor = myset.find({'name': {'$gt': '小西'}}, {'_id': 0})
#  循环遍历得到的每一个结果都是文档字典
# for i in cursor:
#   print(i['name'],'---',i['King'])
# print(cursor.next()) #  获取游标的下一个结果
#   cursor 调用 limit,skip,sort 后得到的仍然是结果游标对象
# for i in cursor.skip(1).limit(3):
#   print(i)
# 按照king排序
# for i in cursor.sort([('King',1)]):
#   print(i)
# r = myset.find_one({'King':' 康熙 '},{"_id":0})
# print(r)# ************** update *************# myset.update_one({"King":' 康熙 '},{'$set':{"king_name":' 玄烨 '}})
# myset.update_many({"King":' 雍正 '},{"$set":{'king_name':' 胤禛 '}})
# myset.update({"King":' 乾隆 '},{"$set":{'king_name':' 弘历 '}},multi=True)
# myset.update_one({"King":' 光绪 '},{'$set':{"name":'小白'}},upsert=True)1# ************ delete *************# myset.delete_one({'King':' 乾隆 '})
# myset.delete_many({"king_name": None})
# myset.remove({"King":' 雍正 '},multi=False)
# r = myset.find_one_and_delete({'King':' 乾隆 '})
# print(r)# *************** index ***************#  参数 'name' ==> [('name',1)]
# index1 = myset.create_index('name')
# index2 = myset.create_index([('name', -1)],name="NAME",sparse=True)
# print("index1 = ", index1)
# print("index2 = ", index2)
#  删除索引
# myset.drop_index('NAME')
# myset.drop_index([('name',1)])
# myset.drop_indexes()
#  查看索引
# for i in myset.list_indexes():
# print(i)# ************ aggregation **********myset = db.class0 # 更换操作集合
pipe = [{'$match': {'gender': {'$exists': True}}},{'$sort': {'age': 1}},{'$project': {'_id': 0}}
]
cursor = myset.aggregate(pipe)
for i in cursor:
print(i)
# 关闭连接
conn.close()
from pymongo import MongoClient
import bson.binary
conn = MongoClient('localhost', 27017)
db = conn.images
myset = db.girl
#  存储图片
# with open('./test.jpg', 'rb') as f:
#    data = f.read()
# # 将data转换为bson格式
# content = bson.binary.Binary(data)
# #  插入到集合
# dic = {'filename': 'girl.jpg', 'data': content}
# myset.insert_one(dic)
#  提取文件
img = myset.find_one({'filename':'girl.jpg'})
# print(img)
with open('mm.jpg','wb') as f:f.write(img['data'])
conn.close()

文档型非关系数据库MongoDB经验总结相关推荐

  1. 悉数11种主流NoSQL文档型数据库

    悉数11种主流NoSQL文档型数据库 文档型数据库是NoSQL中非常重要的一个分支,它主要用来存储.索引并管理面向文档的数据或者类似的半结构化数据.顾名思义,文档型数据库(面向文档数据库)的关键核心概 ...

  2. mongodb单表最大记录数_SpringBoot+Cloud全家桶微服务实战项目之文档型数据库MongoDB四...

    ​一.MongoDB简介以及使用场景 MongoDB 是一个跨平台的,面向文档的数据库,是当前 NoSQL 数据库产品中最热门的一种.它介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富, ...

  3. spring cloud alibaba微服务原理与实战_SpringBoot+Cloud全家桶微服务实战项目之文档型数据库MongoDB四...

    ​一.MongoDB简介以及使用场景 MongoDB 是一个跨平台的,面向文档的数据库,是当前 NoSQL 数据库产品中最热门的一种.它介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富, ...

  4. 面向文档的NoSQL数据库MongoDB

    NoSQL优势 全称:Not Only SQL 不仅仅是数据库 海量的扩展能力 读写高性能 与关系型数据库(RDBMS)相辅相成 NoSQL产品 键值存储型(Key-Value) Redis/Codi ...

  5. 关系型数据库到文档型数据库的跨越

    1. 简介 在文档型NoSQL数据库出现之前,许多开发者一直绞尽脑汁思考,希望能想出更好的处理关系型数据库技术的方法,如今他们可能要跳出那种思维而另辟蹊径.本文将介绍关系型数据库和分布式文档型数据库的 ...

  6. 关系型到文档型的跨越:颠覆你对数据库数据模型的认识

    1. 简介 在文档型NoSQL数据库出现之前,许多开发者一直绞尽脑汁思考,希望能想出更好的处理关系型数据库技术的方法,如今他们可能要跳出那种思维而另辟蹊径.本篇白皮书将介绍关系型数据库和分布式文档型数 ...

  7. 文档型信息交互设计及相关技术实现

    本文信息交互是指办公和经营管理活动中所产生的公众或定向业务信息,以及在信息共享过程中,以业务规则形式衍生出的评论.评价.回复.转发等业务信息延续. 信息交互设计目标 共享业务信息,并支持限定范围 共享 ...

  8. 文档型数据库列一般都是弱项

    文档型数据库一般都是以行为基础得,添加更新删除等操作,因为文档型数据的一般存储结构都是键值对.所以对列的概念很弱,比如有一些文档数据库,是无法对单列操作的,有时候想修改一列的值,只能所有数据全部重新添 ...

  9. 文档型数据库设计模式-如何存储树形数据

    在数据库中存储树形结构的数据,这是一个非常普遍的需求,典型的比如论坛系统的版块关系.在传统的关系型数据库中,就已经产生了各种解决方案. 此文以存储树形结构数据为需求,分别描述了利用关系型数据库和文档型 ...

最新文章

  1. SSH服务器管理与Termux使用
  2. asp.net中URL参数传值中文乱码的三种解决办法
  3. [architecture]-Armv8 Cryptographic Extension介绍
  4. @requestparam map 接收前端的值_前端面试总结篇(初级)
  5. MySQL——高阶语句(中)
  6. XPath语法规则及实例
  7. JsonPath工具类封装
  8. svn java.mine_最好的一般SVN忽略模式?
  9. shell监控Nginx服务是否存在的脚本
  10. javascript基础知识(13) Date
  11. 【超链接】一些OI学习网站
  12. [转载][工具]Eclipse Console 加大显示的行数,禁止弹出
  13. 国家计算机房机柜接地图集,中国铁塔机房及室外机柜标准图集.pdf
  14. B树和TreeSet与TreeMap
  15. MIUI主题风格_一种Android系统换肤功能的设计
  16. winform控件焦点设置
  17. Installing vipm-17.0.2018-linux
  18. (JDBC四)JDBC实例(b)
  19. 尚硅谷谷粒商城第九天 模板引擎-Thymeleaf
  20. [Python核心技术与实战学习] 18 单元测试unittest 库

热门文章

  1. 关于“知识共享”的几个基本概念
  2. Windows-Windows 10显示两个显示器,两个显示器都能分别显示
  3. 虚拟分区魔术师 v4.6 绿色
  4. java爬虫之下载txt小说
  5. 解决mac终端放大字体重启又变小了
  6. nas java_小白入门NAS—快速搭建私有云教程系列(一)
  7. 数据库之区分DB\DBMS\DBS
  8. Gensim官方教程翻译(五)——英文维基百科的实验
  9. 2022/1/29周末培训小结(hgame)
  10. springboot yml文件不是绿叶子问题