mongodb的使用

MongoDB

官方文档:https://docs.mongodb.com/v3.6/

基本介绍

MongoDB 是由 C++ 语言编写并基于分布式文件存储的开源数据库系统,是一款介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的 NOSQL 数据库。它面向文档存储,而且安装和操作起来都比较简单和容易,而且它支持各种流行编程语言进行操作,如 PYTHON,JAVA,C++,PHP,C#,RUBY 等。

MongoDB 将数据存储为一个文档,数据结构由键值 (key=>value) 对组成。MongoDB 的文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

术语对比

SQL Mongodb
库(database) 库(database)
表(Talbe) 集合(Collection)
行 / 记录(Row) 文档(Document)
列 / 字段(Col) 字段 / 域(Field)
主键(Primary Key) 对象 ID(ObjectId)
索引(Index) 索引(Index)

基本安装

目前最新版本为 4.4 版本,ubuntu18.04 中默认安装的是 3.6 版本【可以继续基于这个版本进行学习,这块内容跳过即可】。

如果要在 ubuntu18.04 中安装最新 4.4 版本 mongodb,则需要完成以下命令步骤:

# 安装依赖包
sudo apt-get install libcurl4 openssl
# 关闭和卸载原有的 mongodb
service mongodb stop
sudo apt-get remove mongodb

# 导入包管理系统使用的公钥
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
# 如果命令执行结果没有显示 OK,则执行此命令在把上一句重新执行:sudo apt-get install gnupg

# 注册 mongodb 源
echo "deb [arch=amd64,arm64] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

# 更新源
sudo apt-get update

# 安装 mongodb
sudo apt-get install -y mongodb-org=4.4.2 mongodb-org-server=4.4.2 mongodb-org-shell=4.4.2 mongodb-org-mongos=4.4.2 mongodb-org-tools=4.4.2

# 创建数据存储目录
sudo mkdir -p /data/db

# 修改配置,开放 27017 端口
sudo vim /etc/mongodb.conf,把12行附近的port=27017左边的#号去掉

启动和关闭 MongoDB

# 重新加载配置,并启动 mongodb
sudo systemctl daemon-reload
sudo systemctl start mongod

# 查看运行状态
sudo systemctl status mongod
# 如果 mongodb 状态为 stop,则运行 sudo systemctl enable mongod

# 停止 mongodb
sudo systemctl stop mongod

# 重启 mongodb
sudo systemctl restart mongod

进入交互终端

MongoDB 安装完成后,默认是没有权限验证的,默认是不需要输入用户名密码即可登录的

也可以启动权限认证,但是必须注意:

mongodb 默认是没有管理员账号的,所以要先切换到 admin 数据库添加管理员账号,再开启权限认证,否则就玩大了。

# 进入交互终端
mongo

效果:

MongoDB shell version v4.4.2
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2c920d56-ddbb-4649-9191-a3bd4506a2d2") }
MongoDB server version: 4.4.2
---
The server generated these startup warnings when booting: 
		# 警告:强烈建议使用 XFS 文件系统,并使用 WiredIger 存储引擎。
		# 解释:因为当前 ubuntu 使用的是 ext4 文件系统,mongodb 官方建议使用 XFS 文件系统功能更能发挥 mongodb 的性能,忽略不管
        2020-11-23T16:23:34.416+08:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
        # 警告:当前 mongodb 没有为数据库启用访问控制。对数据和配置的读写访问是不受限制的。
        # 解释:后面会创建数据库用户采用密码登陆的。暂时不用管
        2020-11-23T16:23:35.046+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).
    The monitoring data will be available on a MongoDB website with a unique URL accessible to you
    and anyone you share the URL with. MongoDB may use this information to make product
    improvements and to suggest MongoDB products and deployment options to you.

    To enable free monitoring, run the following command: db.enableFreeMonitoring()
    To permanently disable this reminder, run the following command: db.disableFreeMonitoring()

mongod 是处理 MongoDB 系统的主要进程。主要负责处理数据请求,管理数据存储,和执行后台管理操作。

当我们运行 mongod 命令意味着正在启动 MongoDB 进程, 并且在后台运行。

mongo 是一个命令行工具,用于连接一个特定的 mongod 实例。

当我们没有带参数运行 mongo 命令它将使用默认的端口号 27017 和 localhost 进行连接

退出交互终端

exit
# quit()

为 MongoDB 创建用户

查看版本

mongo --version
# 或者终端内部使用 version()

基本操作

mongoDB 默认数据

通用操作

help # 查看帮助文档
db.serverStatus()   # 当前服务器操作
db.getMongo()
show logs
show log <logname>

用户管理

db.createUser(user, writeConcern)

创建一个数据库新用户用 db.createUser() 方法,如果用户存在则返回一个用户重复错误。

语法

{
    user: "<name>",   # 用户名
    pwd: "<cleartext password>",  # 密码
	customData: { <any information> }, # 用户身份相关介绍 
	roles: [ # 角色和权限分配
		{ role: "<role>", db: "<database>" } | "<role>",
		...
    ]
}

mongo 的用户是以数据库为单位来建立的,每个数据库有自己的管理员。

管理员可以管理所有数据库,但是不能直接管理其他数据库,要先在 admin 数据库认证后才可以。

管理员的权限设置包含了 2 块,分别是角色和权限,由 roles 属性进行设置。

内置角色

数据库用户角色:read、readWrite; 
数据库管理角色:dbAdmin、dbOwner、userAdmin;
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager; 
备份恢复角色:backup、restore; 
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase 
超级用户角色:root
# 有几个角色间接或直接提供了系统超级用户的访问权限(dbOwner 、userAdmin、userAdminAnyDatabase)

内置权限

Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限

给 Admin 数据库创建账户管理员

当前账号只能用于管理数据库账号,不能进行数据库操作。

# 进入 / 切换数据库到 admin 中
use admin
# 创建管理员账号
db.createUser({
	user: "admin",
	pwd: "123",
	roles: [
		{role: "userAdminAnyDatabase",db:"admin"}
	]
})

创建超级管理员

当前账号可以进行数据库相关操作。

# 进入 / 切换数据库到 admin 中
use admin
# 创建超级管理员账号
db.createUser({
    user: "root",
    pwd: "123",
    roles: [
    	{ role: "root", db: "admin" }
    ]
})

创建用户自己的数据库的角色

帐号是跟着数据库绑定的,所以是什么数据库的用户,就必须在指定库里授权和验证!!!

# 切换数据库,如果当前库不存在则自动创建
use mofang
# 创建管理员用户
db.createUser({
    user: "mofang",
    pwd: "mofang",
    roles: [
        { role: "dbOwner", db: "mofang"}
    ]
})

查看系统中所有的用户

需要切换到 admin 中使用账号管理员的权限进行操作

use admin
db.auth('admin','123')
db.system.users.find()

查看当前库下的用户

只需要切换到对应的库中即可查看

use mofang
show users

删除用户

db.system.users.remove(json 条件)

# 有多种删除方式,下面是根据 user 用户名删除用户
db.system.users.remove({user:"mofang"})

修改密码

必须切换到对应的库下

db.changeUserPassword("账户名", "新密码")

use mofang
db.changeUserPassword("mofang", "123456")

开启 mongodb 账户认证机制

sudo vim /etc/mongodb.conf
# 找到 22 行附近的 auth=true,去掉左边注释符号 (#)
auth=true
:wq
# 重启 mongdb,配置生效
sudo systemctl restart mongod

库管理

  • 显示所有数据库列表【空数据库不会显示,或者说空数据库已经被删除了。】

    show dbs
    

  • 切换数据库,如果数据库不存在则创建数据库。

    use  <database>
    

  • 查看当前工作的数据库

    db
    db.getName()
    

  • 删除当前数据库,如果数据库不存在,也会返回{"ok":1}

    db.dropDatabase()
    

  • 查看当前数据库状态

    > db.stats()
    

    {
    "db" : "mofang",
    "collections" : 0,
    "views" : 0,
    "objects" : 0,
    "avgObjSize" : 0,
    "dataSize" : 0,
    "storageSize" : 0,
    "totalSize" : 0,
    "indexes" : 0,
    "indexSize" : 0,
    "scaleFactor" : 1,
    "fileSize" : 0,
    "fsUsedSize" : 0,
    "fsTotalSize" : 0,
    "ok" : 1
    }

集合管理

  • 创建集合

    在 mongodb 中其实不创建集合,直接添加文档,mongodb 也会自动生成集合的。

    # name 为必填参数,options 为可选参数。capped 若设置值为 true,则 size 必须也一并设置
    db.createCollection(name=<集合名称>, options  = { 
    	capped : <boolean>, # 创建固定集合,固定集合指限制固定数据大小的集合,当数据达到最大值会自动覆盖最早的文档内容 
    	size : <bytes_size>,      # 指定固定集合存储的最大字节数,单位:字节数.
    	max : <collection_size>   # 指定固定集合中包含文档的最大数量,单位:字节数
    })
    

    添加文档到不存在的集合中,mongodb 会自动创建集合,
    db.< 集合名称 >.insert({"name":"python 入门","price" : 31.4})

  • 查看集合列表

    show collections # 或 show tables   或 db.getCollectionNames()
    

  • 删除集合

    db.<集合名称>.drop()
    

  • 查看指定集合信息

    db.getCollection("集合名称")
    

  • 查看当前集合的创建信息

    db.printCollectionStats()
    

文档管理

  • 添加文档

    文档的数据结构和 JSON 基本一样。所有存储在集合中的数据都是 BSON 格式。

    SON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。

    # 添加一个文档
    db.集合名称.insert(<document>)
    db.collection.insertOne(      # 如果文档存在_id主键为更新数据,否则就添加数据。
       <document>,
       {
          writeConcern: <document>
       }
    )
    

    一次性添加多个文档, 多次给同一个集合建议使用 insertMany 比 insertOne 效率更好

    db.collection.insertMany(
    [ <document> , <document>, ... ],
    {
    writeConcern: <document>,
    ordered: <boolean>
    }
    )

  • 更新文档

    db.集合名称.update(
       <query>,   # update的查询条件,一般写法:{"属性":{条件:}}
       <update>,  # update的对象,一般写法 { $set:{"属性":"值"} } 或者 { $inc:{"属性":"值"} }
       {
         upsert: <boolean>, # 可选,默认是false,如果不存在update的记录是否插入, true为插入
         multi: <boolean>,  # 可选,默认是false,只更新找到的第一条记录,如果为true,就把查出来的所有记录全部更新
         writeConcern: <document>  # 可选参数,抛出异常的级别
       }
    )
    

    """
    query 条件可以是:$gt,$gte,$lt,$lte,
    "
    ""

    只更新第一条记录:
    db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );

    全部更新:
    db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );

    只添加第一条:
    db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );

    全部添加进去:
    db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );

    全部更新:
    db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );

    只更新第一条记录:
    db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

  • 查询文档
    db.clo.find().pretty()