MongoDB基础操作

MongoDB是什么

MongoDB是一个基于分布式文件存储的数据库。有C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

  • 基于分布式文件存储数据库(就是一个数据库)
  • C++语言编写
  • 支持的数据结构非常松散,是类似json的bson格式(后期插入修改数据谢json)

json(JavaScript Object Notation,js对象简谱)是一种轻量级的数据交换格式

bson(二进制json)

MongoDB能干什么

  • 存放项目数据
  • 实战工作开发写API接口(重要)

MongoDB在win上的安装

步骤1:下载 http://www.mongodb.com/download-center/community

步骤2:解压

步骤3:创建服务(1. 必须通过管理员身份运行dos窗口,否则没有权限创建失败; 2. 要提前创建数据和日志存放的目录)

bin/mongod.exe --install --dbpath 磁盘目录 --logpath 日志目录

步骤4:启动服务

net start mongodb

步骤5:登录(验证是否安装成功)

MongoDB基本操作

查看数据库

语法:show databases

选择数据库

语法:use 数据库名

image.png

删除数据库

语法:

  1. 通过use语法选中数据库
  2. 通过db.dropDatabase()删除数据库

查看集合

语法:show collections

创建集合

语法:db.createCollection('集合名')

删除集合

语法:db.集合名.drop()

基操小总结

数据库(查看、创建、选择、删除)

查看:show databases

创建:有单独的语法,但是忽略 使用 use 数据库名 做隐式创建

选择:use 数据库名

删除:首先使用use选中数据库,然后通过db.dropDatabase()删除
    1. use 数据库名
    2. db.dropDatabase()

集合(查看、创建、删除)

查看:show collections

创建:db.createCollection('集合名')  忽略,后期插入数据,隐式创建集合

删除:db.集合名.drop()

MongoDB的增删改查

语法:db.集合名.insert(json数据)

说明:集合存在,则直接插入数据;集合不存在,则隐式创建集合后插入数据

练习:在test数据库中的c1集合中插入数据(名字较webopenfather年龄18岁)

use test
db.c1.insert({
    name: 'webopenfather',
    age: 18
})

留心1:数据库和集合不存在都隐式创建
留心2:对象的键统一不加引号,方便看,但是查看集合数据时系统自动加 
留心3:mongodb会给每一条数据增加一个全球唯一的 _id 键

多学一招:_id的组成

image.png

思考1:是否可以自定义_id值?

回答:可以,只需要给插入的json数据中增加_id键即可覆盖(但实战强烈不推荐)

db.c1.insert(_id: 1, name: 'john', age: 18)

思考2:如何插入多条记录?

回答:传递数据,数组中写一个个json数据即可

db.c1.insert([
  {name:'z3', age:3},
  {name:'l4', age:4},
  {name:'w5', age:5}
])

思考3:如何快速插入10条数据

回答: MongoDB底层使用js引擎实现的,所以支持一部分js语法,因此,可以使用for循环

for (var i=1; i<=10; i++) {
  print(i);
}

需求:在test数据库的c2集合中插入10条数据,分别为a1 a2 ... a10
for (var i=1; i<=10; i++) {
  db.c2.insert(name:'a'+i, age:i)
}

基础语法:db.集合名.find(条件 [,查询的列])

条件
    查询所有数据          {}或者不写
    查询age=6的数据       {age: 6}
    查询age=6且性别为男    {age: 6, sex: '男'}
    
查询的列(可选参数)
    不写 —— 这查询全部列(字段)
    {age: 1} —— 只显示age列(字段)
    {age: 0} —— 除了age列(字段)都显示
    留心:不管怎么写,系统自定义的_id都会在

升级语法:

db.集合名.find({键: 值}) 

db.集合名.find({键: {运算符:值}})
运算符 作用
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in in
$nin not in

练习1:查询所有数据

use test
db.c2.find()

练习2:查询年龄大于5岁的数据

use test
db.c2.find({age: {$gt: 5}})

练习3:查询年龄是5岁、8岁、10岁的数据

use test
db.c2.find({age: {$in: [5, 8, 10]}})

练习4:只看年龄列,或者年龄以外的列(_id不管)

use test
db.c2.find({}, {age: 1})    只看年龄列

use test
db.c2.find({}, {age: 0})    不看年龄列

基础语法:db.集合名.update(条件, 新数据 [,是否新增, 是否修改多条])

是否新增:指条件匹配不到数据则插入 true是插入,false否不插入(默认)

是否修改多条:指将匹配成功的数据都修改(true是,false否(默认))

升级语法:

db.集合名.update(条件, 新数据)
                     {修改器: {键: 值}}
修改器 作用
$inc 递增
$rename 重命名列
$set 修改列值
$unset 删除列

准备工作:

use test
for (var i=1; i<=10; i++) {
    db.c3.insert({uname: 'zs'+i, age: i}
}

练习1:将{uname:"zs1"}改为{uname:"zs2"}

use test
db.c3.update({uname:'zs1'}, {uname:'zs2'})
-- 发生问题,默认整个都替换成了{uname:'zs2'},丢失了age数据;即默认为替换,不是修改,可以使用修改语法$set

正确代码:
use test
db.c3.update({uname: 'zs1'}, {$set: {uname: 'zs2'}})

练习2:给{uname:"zs10"}的年龄加2岁, 或减2岁

use test
db.c3.update({uname:'zs10'}, {$inc: {age: 2}}) 加2岁

use test
db.c3.update({uname:'zs10'}, {$inc: {age: -2}}) 减2岁

练习3:修改器综合练习

插入数据:db.c4.insert({uname:"神龙教主", age: 888, who: "男", other: "非国人"})

需求:

uname 改成 教主

age 增加 111

who 改字段 sex

other 删除

实现:

db.c4.update({uname: '神龙教主'}, {
  $set:{uname: '教主'}, 
  $inc:{age: 111}, 
  $rename:{who: 'sex'}, 
  $unset:{other: 1}}
)
db.c4.find().pretty()

练习4:验证语法的最后两个参数

  1. 是否新增:修改name等于zs30的年龄30岁

    use test
    db.c3.find({uname: 'zs30'}, {$set: {age: 30}}, true)
    
  2. 是否修改多条

    use test
    db.c3.find({}, {$set: {age: 20}}, false, true)
    

语法:db.集合名.remove(条件 [, 是否删除删除一条])

注意:是否删除一条参数,默认为false,即删除多条

小总结

增Create

db.集合名.insert(JSON数据)

删Delete

db.集合名.remove(条件 [,是否删除删除一条])

改Update

db.集合名.update(条件, 新数据 [,是否新增, 是否修改多条])

查Read

db.集合名.find(条件 [,查询的列])

MongoDB排序和分页

数据准备

use test
db.c1.insert({_id:1, name:"a", sex:1, age:1})
db.c1.insert({_id:2, name:"b", sex:1, age:2})
db.c1.insert({_id:3, name:"c", sex:2, age:3})
db.c1.insert({_id:4, name:"d", sex:2, age:4})
db.c1.insert({_id:5, name:"e", sex:2, age:5})

db.c1.find()

排序

语法:db.集合名.find().sort(JSON数据)

说明:键——就是要排序的列(字段);值:1 升序,-1降序

练习:年龄升序或降序

use test
db.c1.find().sort({age:1})  升序

use test
db.c1.find().sort({age:-1}) 降序

limit和skip方法

语法:db.集合名.find().sort().skip(数字).limit(数字)

说明:skip跳过指定数量的数据,limit限制查询数据的数量

练习1:按降序查询,查询2条数据

use test
db.c1.find().sort({age:-1}).limit(2)

练习2:按降序查询,跳过2条然后查询2条数据

use test
db.c1.find().sort({age:-1}).skip(2).limit(2)

注意:skip和limit同时出现时,skip先执行,后执行limit,不管他们在语句中如何出现,即db.c1.find().sort({age:-}).limit(2).skip(2)和上面的效果一样

实战分页

需求:数据库1~10数据,每页显示2条(5页)

实现:

1页 1,2
2页 3,4
3页 5,6
4页 7,8
5页 9,10

skip计算公式:(当前页-1) * 每页显示条数

db.集合名.find().skip((page-1)*num_of_page).limit(2)

小总结

db.集合名.find()
.sort({列: 1/-1}) 排序
.skip(数字)  跳过指定数量
.limit(数字) 限制总数量
.count()   统计总数量

MongoDB聚合查询

语法:

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

常用管道:

$group: 将集合中的文档分组,用于统计结果
$match: 过滤数据,输出符合条件的文档
$sort: 聚合数据进一步排序
$skip: 跳过指定文档数
$limit: 限制集合数据返回文档数
...

常用表达式:

$sum: 总和 $sum:1同count表示统计
$avg: 平均
$min: 最小值
$max: 最大值
...

数据准备

use test
db.c1.remove()
db.c1.insert({_id:1, name:"a", sex:1, age:1})
db.c1.insert({_id:2, name:"b", sex:1, age:2})
db.c1.insert({_id:3, name:"c", sex:2, age:3})
db.c1.insert({_id:4, name:"d", sex:2, age:4})
db.c1.insert({_id:5, name:"e", sex:2, age:5})

db.c1.find()

练习

  • 统计男生、女生的总年龄

    db.c1.aggregate([
      {
          $group:{
              _id: "$sex",
              re: {$sum: "$age"}
          }
      }
    ])
    
  • 统计男生、女生的总人数

    db.c1.aggregate([
      {
          $group: {
              _id: "$sex",
              num: {$sum: 1}
          }
      }
    ])
    
  • 求学生的总数和平均年龄

    db.c1.aggregate([
      {
          $group: {
              _id: null
              num: {$sum: 1},
              avg_age: {$avg: "$age"}
          }
      }
    ])
    
  • 查询男生、女生人数,按人数升序

    db.c1.aggregate([
      {
          $group: {
              _id: "$sex",
              rs: {$sum: 1}
          }
      },
      {
          $sort: {rs: 1}
      }
    ])
    

MongoDB优化索引

数据库中的索引

  • 说明:索引是一种排序好的便于快速查询的数据结构
  • 作用:帮助数据库高效的查询数据

索引的优缺点

  • 优点
    1. 提高数据查询的效率,降低数据库的IO成本
    2. 通过索引对数据进行排序,降低数据排序的成本,减低CPU的消耗
  • 缺点
    1. 占用磁盘空间
    2. 大量索引影响sql语句效率,因为每次插入和修改数据都需要更新索引

语法

  • 创建索引:db.集合名.createIndex(待创建索引的列 [,额外选项])

    参数:

    • 待创建索引的列:{键: 1, ..., 键: -1}

      说明:1表升序,-1表降序。例如{age:1}表示创建age索引并按照升序的方式存储

    • 额外选项:设置索引的名称或者唯一索引等等

  • 删除索引

    全部删除:db.集合名.dropIndexes()

    删除指定:db.集合名.dropIndex(索引名)

  • 查看索引:db.集合名.getIndexes()

练习

准备:向数据库中新增十万条数据

use test
for(var i=0; i<100000; i++) {
    db.c1.insert({name:"aaa"+i, age:i})
}

创建普通索引

需求:给name添加普通索引

  • 练习1:给name添加普通索引

    db.c1.createIndex({name: 1})
    
  • 练习2:删除name索引

    db.c1.dropIndex('name_1')
    
  • 练习3:给name创建索引起名name_index

    db.c1.createIndex({name:1}, {name:"name_index"})
    

创建复合/组合索引

需求:给name和age添加组合索引

说明:就是一次性给两个字段建立索引

语法:db.集合名.createIndex({键1: 方式1, 键2: 方式2})

db.createIndex({name:1, age:1})

创建唯一索引

需求:给name添加普通索引

语法:db.集合名.createIndex(带添加索引的列, {unique: 列名})

  • 练习1:删除全部索引

    db.c1.dropIndexes()
    
  • 练习2:设置唯一索引

    db.c1.createIndex({name:1}, {unique:name})
    
  • 测试唯一索引特性

    对于唯一索引的列,它对应列的数据也必须唯一

分析索引

  • 语法:db.集合名.find().explain('executionStats')

  • 练习

    测试:age未添加索引的情况

    db.c1.find({age:18}).explain('executionStats')
    

    测试:age添加索引的情况

    db.createIndex({age:1})
    db.c1.find({age:18}).explain('executionStats')
    

选择规则(如何选择合适的列创建索引)

  • 为常作条件、排序、分组的字段建立索引
  • 选择唯一性索引
  • 选择较小的数据列,为较长的字符串使用前缀索引

MongoDB权限机制

创建账号:

db.createUser({
    "user": 你的账号,
    "pwd": 你的密码,
    "roles": [{
        role: 角色,
        db: 所属数据库
    }]
})

角色

-- 角色种类
超级用户角色:root
数据库用户角色:read、readWrite
数据库管理角色:dbAdmin、userAdmin
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
备份恢复角色:backup、restore
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

-- 角色说明
root:只在admin数据库中可用。超级账号,超级权限
read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库

开启验证模式

开启验证模式概念:指用户需要输入账号密码才能登录使用

操作步骤:

1. 添加超级管理员
2. 退出卸载服务
3. 重新安装需要输入账号密码的服务
4. 启动服务 -> 登录测试
  • 步骤1:添加超级管理员

    使用DOS命令行
    use admin
    db.createUser({
      "user": "admin",
      "pwd": "admin888",
      "roles": [{
          role: "root",
          db: "admin"
      }]
    })
    
  • 步骤2:退出卸载服务

    使用管理员身份打开DOS窗口,进入MongoDB的bin目录下,执行
    mongod --remove
    
  • 步骤3:重新安装徐奥输入账号密码的服务

    使用管理员身份打开DOS窗口,进入MongoDB的bin目录下,执行
    mongod --install --dbpath db数据路径 --logpath 日志路径 --auth
    
  • 步骤4:启动服务 -> 登录测试

    启动服务:net start mongodb
    
    进入:mongo
    

通过超级管理员账号登录

用户是给数据库加的

方法1:mongo 服务器IP地址:端口号/数据库 -u 用户名 -p 密码

方法2:a-先登录,b-选择数据库,c-输入db.auth(用户名, 密码)

MongoDB备份还原

备份数据库mongodump

  • 语法

    导出数据语法:mongodump -h -port -u -p -d -o
    导出语法说明:
    -h    host    服务器IP地址(一般不写,默认本机)
    -port 端口(一般不写,默认27017)
    -u    user    账号
    -p    pwd     密码
    -d    database    数据库(数据库不写则导出全部)
    -o    open    备份到指定目录
    
  • 练习:备份所有数据:mongodump -u admin -p admin888 -o C:\MongoDB\Server\bin\bak

  • 练习:备份指定数据:mongodump -u shop1 -p admin888 -d shop -o C:\MongoDB\Server\bin\bak2

还原数据库mongorestore

  • 语法:

    还原数据语法:mongorestore -h -port -u -p -d --drop 备份数据目录
    还原数据说明:
    --drop    先删除数据库再导入,不写则覆盖
    其他参数同备份
    
  • 练习:还原所有数据:mongorestore -u admin -p admin888 --drop C:\MongoDB\Server\bin\bak

  • 练习:还原指定数据:mongorestore -u shop1 -p admin888 --drop C:\MongoDB\Server\bin\bak2

接口数据:

{
    meta: {
        msg: 提示信息,
        status: 状态码(200/201/301/400/401/403/404/500)
    },
    data:数据
}

你可能感兴趣的:(MongoDB基础操作)