700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 文档型非关系数据库MongoDB经验总结

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

时间:2021-12-18 16:56:41

相关推荐

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

文档型非关系数据库MongoDB

数据库基础概念

数据:能够输入到计算机中并被识别处理的信息集合数据结构:研究一个数据集合中,数据元素关系数据库:按照数据结构,存储管理数据的仓库。数据仓库是在数据库管理系统管理控制下在一定介质中

创建的数据库管理系统:数据库管理软件,用于建立维护操作数据库数据库系统:由数据库和数据库管理系统等构成的数据库开发工具集合。

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

关系型数据库

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

1: 常见关系型数据库:Oracle DB2 SQLServer MySQL SQLite

2:优缺点

优点:逻辑清晰,容易理解,结构类似常见表格

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

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

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

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

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

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

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

​ 不是采用关系模型构建的数据库

​ 键值型 : Redis

​ 列存储 : HBase

​ 文档型 : MongoDB

​ 图形 : Graph

2:优缺点

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

​ 使用灵活,容易扩展

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

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

3:应用场景

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

MongoDB数据库

mongodb特点

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

​ 开源数据库,使用广泛

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

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

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

​ 方便扩展和部署

MongoDB 安装

Linux : sudo apt-get install mongodbMac OS: brew install mongodbWindows: -->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":1,"NAME":'Lily',"AGE" :17},{"_id":2,"NAME":'Lucy',"AGE" :18}

2:基本概念对比

数据库操作

创建数据库: 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

数据库运行监控

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

集合操作

创建集合

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

查看集合:

show collectionsshow tables

集合命名规则

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

删除集合

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

集合重命名

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

文档操作

什么是文档

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

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

​ mongodb文档数据 bson类型数据

文档键值对特点:

​ 无序的

​ 通过键取其值

​ 不能重复

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

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

数据类型:

​ 整型 int : 整数

​ 浮点型 double : 小数

​ 布尔 boolean : true false

​ 字符串 string : utf-8字符串

​ ObjectId : id 对象 自动生成的不重复值

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

集合中文档设计

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

数据操作

插入文档

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 + insertManydb.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 tablequery : 是一个 键值对文档{},空则表示所有以键值对表示筛选条件,往往配合查找操作符完成* field : 是一个键值对文档{}, field:0表示不查找这个与,field:1表示查找这个域。_id 域如果不想查找 _id:0其他域设置要么全为 0 要么全为 1e.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):功能: 修改所有符合条件的文档参数: 同 updateOnee.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 : 指定数据插入位置 配合$eache.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() 获取当前时间或者字符串制定时间"-01-01 08:08:08""0101 08:08:08""0101"e.g. 传入制定时间db.class1.insertOne({book:'Python疯狂',date:ISODate("-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 分组聚合 需要配合统计操作符* 统计求和 : $sume.g. 按性别分组统计每组人数db.class0.aggregate({$group:{_id:'$gender',num:{$sum:1}}})* 求平均数 : $avg e.g. 按性别分组求平均年龄db.class0.aggregate({$group:{_id:'$gender',num:{$avg:'$age'}}})* 求最大最小值 : $max / $mine.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 filee.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 MongoClientconn = 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 bson1. 将文件内容转换为bson二进制格式存储 content = bson.binary.Binary(bytes)功能: 将python字节串转换为bson格式参数: 要转换的字节串返回值: bson数据2. 将bson数据 插入到mongo数据库文档中

示例

"""pymongo 模块操作示例用于数据增删改查索引聚合方法的参考"""from pymongo import MongoClient# 创建数据库连接conn = MongoClient('localhost', 27017)# 创建数据库对象和集合对象db = conn.stumyset = 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 MongoClientimport bson.binaryconn = MongoClient('localhost', 27017)db = conn.imagesmyset = 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()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。