MongoDB是一个基于分布式 文件存储的NoSQL数据库,适合存储JSON风格文件的形式。

  • 三元素:数据库、集合和文档。

    • 文档:对应着关系数据库中的行,就是一个对象,由键值对构成,是json的扩展Bson形式,示例

      1. {'name':'guojing','gender':'男'}
    • 集合:类似于关系数据库中的表,储存多个文档,结构不固定,示例
      1. {'name':'guojing','gender':'男'}
      2. {'name':'huangrong','age':18}
      3. {'book':'shuihuzhuan','heros':'108'}

一、环境安装与运行

  • 安装

    1. sudo apt-get install mongodb

  配置文件为 /etc/mongodb.conf,默认端口号:27017

  • 启动服务器

    1. sudo service mongodb start #相当于执行命令 sudo mongod --config /etc/mongod.conf
  • 关闭服务器

    1. sudo service mongodb stop
  • 重启服务器

    1. sudo service mongodb restart #修改了配置文件/etc/mongodb.conf后,需要重启mongodb服务器让配置生效
  • 启动客户端

    1. sudo mongo

二、数据库操作

  • 查看当前数据库

    1. db
  • 查看所有数据库

    1. show dbs
  • 切换(或创建)数据库

    1. use 数据库名

    切换数据库,如果数据库不存在,当插入数据或创建集合时,会自动创建这个数据库

  • 删除数据库

    1. db.dropDatabase()

    删除当前指向的数据库,如果不存在,则什么也不做

三、集合操作

  • 创建

    1. db.createCollection(name[,options])
    2. #name集合名称
    3. #options可选,是一个用于指定集合配置的文档,其中capped参数默认不设置上限(false),若设置上限(true)则需要指定参数size,单位字节
    1. #不设置集合大小
    2. db.createCollection("stu")
    3. #设置集合大小
    4. db.createCollection("sub", { capped : true, size : 10 } )
  • 查看当前数据库集合

    1. show collections
  • 删除集合

    1. db.集合名.drop()

四、数据操作

  • 插入

    1. db.集合名.insert(文档) db.集合名.insert([文档...])
      #如果不指定_id字段,则分配一个唯一的ObjectId;如果指定_id字段,且_id已经存在时,不做任何操作;如果一次性插入多条数据,以数组的方式传入文档
    1. # 不指定_id
    2. db.stu.insert({name:'gj',gender:1})
    3.  
    4. #指定_id
    5. s1={_id:'20160101',name:'hr'}
    6. s1.gender=0
    7. db.stu.insert(s1)
  • 删除--(注意justOne参数)

    1. db.集合名.remove(条件,{justone:<boolean>}) #参数justOne默认false,删除多条
    1. # 只删除匹配到的一条数据
    2. db.stu.remove({gender:0},{justOne:true})
    3.  
    4. #删除所有
    5. db.stu.remove({})
  • 修改--(注意$set以及multi参数)

    1. db.集合名.update({条件},$操作符,{multi: <boolean>}]) #参数multi只和$操作符一起使用,默认false,只修改一条数据,true表示修改多条数据
    1. # 不使用操作符$set,修改整条文档
    2. db.stu.update({name:'hr'},{name:'mnc'})
    3.  
    4. #使用操作符$set指定属性修改
    5. db.stu.update({name:'hr'},{$set:{name:'hys'}})
    6.  
    7. #multi参数和$set一起使用,修改多条文档
    8. db.stu.update({},{$set:{gender:0}},{multi:true})
  • 保存

    1. db.集合名.save(document)
      #在手动插入_id字段时,如果_id已经存在,做全文档更新操作,其余均表示插入数据。
    1. db.stu.save({_id:'20160102','name':'yk',gender:1})
    2. db.stu.save({_id:'20160102','name':'wyk'}) #对上述文档做修改
  • 查询

    • 基本查询

      1. db.集合名.find({条件文档}) #查询所有
      2. db.集合名.findOne({条件文档}) #只查询第一条
      3. db.集合名.find({条件文档}).pretty() #结果格式化输出
    • 比较运算符

      • 等于:默认,没有运算符
      • 小于: $lt
      • 小于等于: $lte
      • 大于:$gt
      • 大于等于:$gte
      • 不等于:$ne
        1. #查询年龄大于等于18的学生
        2. db.stu.find({"age":{$gte:18}})
    • 逻辑运算符

      • 逻辑与:默认
      • 逻辑或:$or
        1. # 查询年龄大于或等于18,并且性别为1的学生
        2. db.stu.find({"age":{$gte:18},"gender":1})
        3.  
        4. #查询年龄大于18,或性别为0的学生
        5. db.stu.find({$or:[{"age":{$gt:18}},{"gender":1}]})
        6.  
        7. #查询年龄小于18或者大于20,性别为1的学生
        8. db.stu.find({$or:[{"age":{$lt:18}},{"age":{$gt:20}}],"gender":1})
    • 范围运算符

      • 在某个范围$in,后面接数组
      • 不在某个范围$nin,后面接数组
        1. #查询年龄18、20以及22岁的学生
        2. db.stu.find({"age":{$in:[18,20,22]}})
        3.  
        4. #查询年龄不等于18或20的学生
        5. db.stu.find({"age":{$nin:[18,20]}})
    • 正则表达式

      • 使用/表达式/或者$regex

        1. #查询姓黄的学生
        2. db.stu.find({"name":/^黄/})
        3. db.stu.find({"name":{$regex:"^黄"}})
    • 自定义查询

      • 使用$where:function(){return 满足条件的数据表达式}------运算符使用js语法,比如逻辑与(&&),逻辑或(||)

        1. #查询年龄18-22的学生
        2. db.stu.find({$where:function(){return this.age>18 && this.age<22}})
        3.  
        4. #查询年龄小于18或者大于22的学生
        5. db.stu.find({$where:function(){return this.age<18 || this.age>22}})
    • 投影

      • 只显示部分字段

        1. db.集合名.find({条件},{字段名:1,...}) #1表示该字段显示,0不显示;_id列默认显示,不显示需要明确设置为0
        1. #查询姓名和年龄(显示_id)
        2. db.stu.find({},{name:1,gender:1})
        3.  
        4. #查询姓名和年龄(不显示_id)
        5. db.stu.find({},{_id:0,name:1,gender:1})
    • skip

      • 跳过指定数量的文档

        1. db.集合名.find({条件}).skip(number) #number默认为0
        1. #查询从第3条开始的学生信息
        2. db.stu.find().skip(2)
    • limit

      • 读取指定数量的文档

        1. db.集合名.find({条件}).limit(number) #不写number参数,默认读取所有文档
        1. #读取3条学生信息
        2. db.stu.find().limit(3)
    • skip和limit合用

      • 不区分先后顺序

        1. #查询第5-9条学生信息
        2. db.stu.find().skip(4).limit(5) #相当于跳过4条数据,选5条
    • sort

      • 对结果集进行排序

        1. db.集合名称.find({条件}).sort({字段:1,...}) #1表示升序,-1表示降序
        1. #根据性别降序,再根据年龄升序
        2. db.stu.find().sort({"gender":-1,"age":1})
    • count

      • 对结果集中文档数目进行统计,返回整数

        1. db.集合名.find({条件}).count()
        2. 或者
        3. db.集合名.count({条件})
        1. #统计年龄大于20的男生人数
        2. db.stu.count({"age":{$gt:20},"gender":1})
    • distinct

      • 对数据去重,返回的是一个列表

        1. db.集合名.distinct("字段名",{条件}) 

五、聚合(aggregate)

  • 聚合主要用于计算数据,类似sql中的sum()、avg()

    1. db.集合名.aggregate([{管道:{表达式}}...])
  • 管道

    • 文档处理完毕后,通过管道进行下一次处理

    • 常用管道:

      • $group:将集合中的文档分组,可用于统计结果
      • $match:过滤数据,只输出符合条件的文档
      • $project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
      • $sort:将输入文档排序后输出
      • $limit:限制聚合管道返回的文档数
      • $skip:跳过指定数量的文档,并返回余下的文档
      • $unwind:将数组类型的字段进行拆分
  • 表达式

    • 处理输入文档并输出

    • 语法:表达式:‘$字段名’

    • 常用表达式:

      • $sum:计算总和,$sum:'$字段'表示求和,注意$sum:1表示计数,
      • $avg:计算平均值
      • $min:获取最小值
      • $max:获取最大值
      • $push:在结果文档中插入值到一个数组中(以列表的方式显示字段值)
      • $first:根据资源文档的排序获取第一个文档数据
      • $last:根据资源文档的排序获取最后一个文档数据
  • $group

    • 文档分组,用于统计结果
    • _id表示分组的依据,使用某个字段的格式为'$字段'
      1. # 统计男、女生人数
      2. db.stu.aggregate([{$group:{"_id":'gender',"couter":{$sum:1}}}])
      3. #结果文档中显示_id和counter的值
    • _id按照null分组,会将集合中所有文档分为一组
      1. # 求学生总人数和平均年龄
      2. db.stu.aggregate([{$group:{_id:null,counter:{$sum:1},average_age:{$avg:"$age"}}}])
    • 使用$$ROOT可以将文档内容加入到结果集的数组中
      1. #统计男、女生信息
      2. db.stu.aggregate([{$group:{_id:"$gender",objects:{$push:"$$ROOT"}}}])
  • $match

    • 过滤数据,输出符合条件文档

      1. #查询年龄大于20的学生
      2. db.stu.aggregate([{$match:{age:{$gt:20}}}])
      3.  
      4. #查询年龄大于20的男、女生人数
      5. db.stu.aggregate([{$match:{age:{$gt:20}}},{$group:{_id:"$gender",counter:{$sum:1}}}])
  • $project

    • 修改输出文档的结构

      1. #查找学生姓名、年龄
      2. db.stu.aggregate([{$project:{"_id":0,"name":1,"age":1}}])
      3.  
      4. #查询男生、女生人数,但仅输出人数
      5. db.stu.aggregate([{$group:{_id:'$gender',counter:{$sum:1}}},{$project:{_id:0,counter:1}}])
  • $sort

    • 将输入文档排序后输出

      1. #查询学生信息,按年龄升序
      2. db.stu.aggregate([{$sort:{age:1}}])
      3.  
      4. #查询男生、女生人数,按人数降序
      5. db.stu.aggregate([{$group:{_id:'$gender',counter:{$sum:1}},{$sort:{counter:-1}}])
  • $limit

    • 限制聚合管道返回的文档数

      1. #查询2条学生信息
      2. db.stu.aggregate([{$limit:2}])
  • $skip

    • 跳过指定数量的文档,并返回余下的文档,$skip和$limi合用时,注意先写skip,再写limit

      1. #查询从第3条开始的学生信息
      2. db.stu.aggregate([{$skip:2}])
      3.  
      4. #统计男生、女生人数,按人数升序,取第二条数据
      5. db.stu.aggregate([{$group:{_id:"$gender",counter:{$sum:1}}},{$sort:{"counter":1}},{$skip:1},{$limit:1}])
  • $unwind

    • 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值

      1. db.集合名称.aggregate([{$unwind:'$字段名称'}]) 

六、索引

  • 提升查询速度

  • 创建大量数据

    1. for(var i=0;i<1000000;i++){db.stu.insert({name:'test'+i,num:i})}
  • 性能分析工具:explain("executionStats")

    1. 查询语句.explain("executionStats")

    'millis'后面显示的是查询时间,单位ms

  • 建立索引

    1. db.集合.ensureIndex({属性:1或-1}) #1表示升序,-1表示降序,建立后的索引名称为"属性_1"或者"属性_-1"

    例如:db.stu.ensureIndex({name:1}),建立后的索引名称为"name_1"

  • 建立唯一索引

    1. db.集合.ensureIndex({属性:1},{"unique":true})
  • 建立联合索引

    1. db.集合名.ensureIndex({属性1:1,属性2:1...})
  • 查看索引

    1. db.集合名.getIndexes()
  • 删除索引

    1. db.集合名.dropIndex("索引名称") 

七、数据库安全

为了更安全的访问mongodb,需要访问者提供用户名和密码,于是需要在mongodb中创建用户。mongodb数据库采用了角色-用户-数据库的安全管理方式。

  • 常用系统角色如下:

    • root:只在admin数据库中可用,超级账号,超级权限
    • Read:允许用户读取指定数据库
    • readWrite:允许用户读写指定数据库
  • 创建超级管理用户:

    1. use admin #首先切换到admin数据库
    2.  
    3. db.createUser({
    4. user:'用户名',
    5. pwd:'密码',
    6. roles:[{role:'root',db:'admin'}]
    7. })
  • 启用安全验证

    • 修改配置文件( /etc/mongodb.conf)

      1. #noauth = true
      2. auth = true #开启安全验证
    • 重启服务

      1. sudo service mongodb restart
    • 终端连接

      1. # sudo mongo -u '用户名' -p '密码' --authenticationDatabase '数据库名'
      2. sudo mongo -u 'admin' -p '密码' --authenticationDatabase 'admin'
  • 普通用户管理

    • 首先使用超级管理员登陆,然后再进行用户管理操作

    • 创建普通用户

      1. db.createUser({
      2. user:'用户名',
      3. pwd:'密码',
      4. roles:[{role:'readWrite',db:'数据库名'}...] #数组里可以有多个角色文档,比如用户在不同的数据库里都有读写权限
      5. })
    • 查看当前数据库的用户

      1. show users
    • 修改用户:可以修改pwd、roles属性

      1. db.updateUser('用户名',{pwd:'新密码',roles:[{'新角色'}...]})
    • 删除用户

      1. use admin #切换到admin数据库
      2. db.system.users.remove(条件)
    • 终端连接

      1. sudo mongo -u '用户名' -p '密码' --authenticationDatabase '数据库名' 

八、复制

复制提供了数据的冗余备份,并在多个服务器上存储数据的副本,允许从硬件故障和服务中断中恢复数据,能够实现无宕机维护(自动故障转移与自动恢复)。

复制至少需要2个节点,其中1个为主节点,其它均为从节点。任何节点均可以成为主节点。

主节点负责所有写入操作,从节点定期轮询主节点获取这些操作并执行这些操作,从而保证从节点的数据与主节点一致。

  • 设置复制节点

    • 创建数据库文件存放目录(自定义)

      1. mkdir ~/Desktop/t1
      2. mkdir ~/Desktop/t2
    • 使用如下格式启动mongod,如果在同一台主机上,注意port不能相同,replSet的名称必须是一致的(名称可以自定义)

      1. sudo mongod --bind_ip 192.168.196.128 --port 27017 --dbpath ~/Desktop/t1 --replSet rs0
      2. sudo mongod --bind_ip 192.168.196.128 --port 27018 --dbpath ~/Desktop/t2 --replSet rs0
    • 连接主服务器(自定义一个)

      1. sudo mongo --host 192.168.196.128 --port 27017
    • 初始化

      1. rs.initiate()

      哪个服务器执行初始化,哪个服务器就作为主节点,rs是mongo服务器中专门用于复本集操作的内置对象

    • 查看当前状态

      1. rs.status()
    • 添加副本集

      1. rs.add("192.168.127.128:8899")
    • 连接从服务器

      1. sudo mongo --host 192.168.196.128 --port 27018
    • 从服务器设置

      1. rs.slaveOk()

      主服务器插入数据,从服务器就可以读取数据了

    • 删除从节点

      1. rs.remove('192.168.196.128:27018') #需要在主服务器操作

      关闭主服务器后再重新启动,会发现原来的从服务器变为了主服务器,新启动的服务器(原来的主服务器)变为了从服务器,但是注意重新设置rs.slaveOk()

九、备份与恢复

  • 备份

    • 语法

      1. sudo mongodump -h 服务器地址 -d 需要备份的数据库 -o 备份数据存放目录
      1. mkdir ~/Desktop/test1_bak #创建存放备份数据的目录
      2. sudo mongodump -h 192.168.196.128:27017 -d test1 -o ~/Desktop/test1_bak
  • 恢复

    • 语法

      1. sudo mongorestore -h 服务器地址 -d 恢复后数据库名 --dir 备份数据所在位置
      1. sudo mongorestore -h 192.168.196.128:27017 -d test2 --dir ~/Desktop/test1_bak/test1

十、python交互

  • 安装pymongo包

    1. sudo pip3 install pymongo
  • 引入包

    1. import pymongo
  • 建立连接并创建客户端

    1. 有安全认证:client=MongoClient("mongodb://用户名:密码@host:27017/数据库名称")
    2. 无安全认证:client=MongoClient("mongodb://localhost: 27017")
  • 获得数据库(以test数据库为例)

    1. db = client.数据库名
    2. 例如:db = client.test
  • 获得集合stu

    1. stu = db.stu
  • 数据操作

    • 查询

      • find_one 查找单个文档

        1. stu1 = stu.find_one({条件}) #返回一条文档,字典类型
      • find 查找多个文档
        1. cursor = stu.find({条件}) #返回迭代器对象cursor
        2. #方式1:用for循环迭代取值
        3. for s in cursor:
        4. print(s) #字典类型
        5.  
        6. #方式2:用next取值
        7. s1 = next(cursor)
        8. s2 = next(cursor)
        9. ...
    • 插入

      • insert_one 插入一条文档

        1. stu.insert_one(文档)
      • insert_many 插入多条文档
        1. stu.insert_many([文档1,文档2...])
    • 更新

      • update 更新匹配到的第一条整条文档

        1. stu.update({条件},文档) #注意条件中的数字一定要写成字符串类型
      • update_one 与$set一起使用,指定属性修改匹配到的第一条文档
        1. stu.update_one({条件},{$set:{文档}})
      • update_many 与$set一起使用,指定属性修改多条文档
        1. stu.update_many({条件},{$set:{文档}})
    • 删除

      • delete_one 删除单条文档

        1. stu.delete_one({条件})
      • delete_many 删除多条文档
        1. stu.delete_many({条件})

MongoDB数据库的使用的更多相关文章

  1. Mongodb数据库学习系列————(一)Mongodb数据库主从复制的搭建

    Mongodb数据库主从复制的搭建 Writeby:lipeng                                    date:2014-10-22 最近项目上用到了位置查询,在网上 ...

  2. 基于C#的MongoDB数据库开发应用(4)--Redis的安装及使用

    在前面介绍了三篇关于MongoDB数据库的开发使用文章,严格来讲这个不能归类于MongoDB数据库开发,不过Redis又有着和MongoDB数据库非常密切的关系,它们两者很接近,Redis主要是内存中 ...

  3. FineReport如何连接和使用MongoDB数据库

    随着NoSQL数据库越来越流行,MongoDB数据库作为NoSQL数据库中的领头羊,使用也越来越广泛.为此,FineReport V8.0版本提供了数据连接和数据集接口,可以通过开发一款可以连接和使用 ...

  4. python操作mongodb数据库

    一.MongoDB 数据库操作 连接数据库 import pymongo conn = pymongo.Connection() # 连接本机数据库 conn = pymongo.Connection ...

  5. NoSql 中Mongodb数据库的使用

    1.NoSql数据库简介 2.MongoDB数据库的简介 3.MongoDB下Windows下的安装

  6. 线上mongodb数据库mLab使用总结

    最近在CNode社区看到有人分享了免费的线上mongodb数据库(容量500M),今天去注册了一下,成功的将线下数据库替换掉了,现在就说一下它的使用和配置需要注意的地方: mLab是一款免费的在线mo ...

  7. mongoDB数据库和Spring MVC的整合

    之前一直用到的项目是Spring MVC+maven+mysql的,最近有些数据需要用到mongoDB数据库,现在做一些总结. 第一步:加载jar.maven配置 <!-- mongodb开始 ...

  8. 【转载】CentOS6.5_X64下安装配置MongoDB数据库

    [转载]CentOS6.5_X64下安装配置MongoDB数据库 2014-05-16 10:07:09|  分类: 默认分类|举报|字号 订阅      下载LOFTER客户端 本文转载自zhm&l ...

  9. 基于C#的MongoDB数据库开发应用(3)--MongoDB数据库的C#开发之异步接口

    在前面的系列博客中,我曾经介绍过,MongoDB数据库的C#驱动已经全面支持异步的处理接口,并且接口的定义几乎是重写了.本篇主要介绍MongoDB数据库的C#驱动的最新接口使用,介绍基于新接口如何实现 ...

  10. 基于C#的MongoDB数据库开发应用(2)--MongoDB数据库的C#开发

    在上篇博客<基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用>里面,我总结了MongoDB数据库的一些基础信息,并在最后面部分简单介绍了数据库C#驱动的 ...

随机推荐

  1. Bazinga means

    Bazinga means Bazinga https://www.dictionary.com/e/slang/bazinga/ refs xgqfrms 2012-2020 www.cnblogs ...

  2. 高阶类 & HOC & anonymous class extends

    高阶类 & HOC & anonymous class extends js 匿名 class extends / mix-ins / 多继承 高阶函数 HOF, 接收一个 funct ...

  3. GitHub Classroom

    GitHub Classroom GitHub Education https://classroom.github.com/classrooms https://classroom.github.c ...

  4. Nestjs 验证对象数组

    route @Patch(':id') patch(@Param('id') id: string, @Body() removeEssayDto: RemoveEssayDto) { return ...

  5. NGK流动性挖矿为何会备受瞩目?

    随着越来越多资金的涌入,参与DeFi项目或挖矿的用户不难发现,使用体验不尽人意,在以太坊网络的DeFi时常需要漫长的等待确认和高昂的GAS费用,加上DeFi流动性挖矿需要相对较高的资金门槛和技术门槛, ...

  6. Python基础之:数字字符串和列表

    目录 简介 数字 字符串 字符串对象str 列表 简介 Python的主要应用是进行科学计算,科学计算的基础就是数字,字符串和列表.本文将会详细的给大家介绍一下这三个数据类型的使用情况. 数字 数字是 ...

  7. window.onresize绑定事件以及解绑事件

    问题描述 在Vue工程中,添加样式,部分需要做到自适应,需要添加resize事件,由于是单页面应用,如果组件初始化的时候绑定事件,在切换页面的时候不去注销事件,如果来回切换,会让resize事件执行多 ...

  8. vue的el-select标签全选以及出现需要有禁用选项

    首先说一下遇到这种问题的解决思路吧,很简单先去https://element.eleme.cn/#/zh-CN 这个官网上找到对应的需求,然后就是拼接数据的问题. 以下是全选的例子: <el-s ...

  9. SpringCloud之服务调用

    1.Ribbon 1.1负载均衡LB 全称Load Balance,将用户的请求平摊到多个服务器上,从而达到系统的HA.集中式LB:在服务消费者和服务提供者之间使用独立的LB设施,如硬件,由该设施负责 ...

  10. Qt update刷新之源码分析(二)

    大家好,我是IT文艺男,来自一线大厂的一线程序员 上次视频给大家从源码层面剖析了Qt update刷新机制的异步事件投递过程,这次视频主要从源码层面剖析Qt刷新事件(QEvent::UpdateReq ...