欢迎光临
我们一直在努力

mongoDB进阶

通过配置文件启动mongo服务器

参数 含义
–dbpath 指定数据库文件存放的目录
–port 端口默认是27017
–fork 以后台守护的方式进行启动
–logpath 指定日志文件输出路径
–config 指定一个配置文件
–auth 以安全方式启动数据库,需要验证账号和密码

直接在命令行中通过mongod --dbpath ...这样启动服务器,如果参数太多的话,就比较麻烦

So,我们可以选择通过运行配置文件的方式启动服务器

首先,要在一个目录下创建一个mongo.config(后缀名无所谓)

注意: log文件会自动生成,但data目录必须优先创建好

//mongo.config文件

dbpath=E:\mongouse\data
#数据库日志存放目录
logpath=E:\mongouse\log
#以追加的方式记录日志
logappend = true
#端口号 默认为27017
port=27017 
#以后台方式运行进程
fork=true 
#开启用户认证
auth=false
#关闭http接口,默认关闭http端口访问
nohttpinterface=true
#mongodb所绑定的ip地址
bind_ip = 127.0.0.1 
#启用日志文件,默认启用
journal=true 
#这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=true 

然后在命令行中输入

mongod --config mongo.config

导入导出数据

  • mongoimport 导入
  • mongoexport 导出
参数 含义
-h[–host] 链接的数据库
–port 端口号
-u 用户名
-p 密码
-d 指定哪个数据库
-c 指定导出的集合
-o 导出的路径
-q 进行过滤的

方法一

mongoexport与导出数据库

mongoexport -d school -c students -o ./stu.bak

导出的是一个文件

整个文件是一个json

mongoimport与导入数据库

mongoimport -h 127.0.0.1 --port 27017 -d school -c students --file stu.bak

默认-h-p--file都可以省略

方法二

mongodump与导出数据库

和上面的区别在于不会转换(上面的会转换成json),适用于数据库中存在二进制数据的情况(二进制是转换不成json的)

导出整个数据库

mongodump -o mdmp

导出其中一个数据库

mongodump -d school -o school.dmp

导出来的样子

(school.dmp文件夹下有一个school文件)

mongorestore与导入数据库

如果想要导入整个数据库

mongorestore mdmp

如果只想导入其中一个数据库

mongorestore -d school mdmp/school

方法三:直接拷贝数据

将整个文件夹拷贝到指定目录下,然后在启动数据库服务器时将其指定为--dbpath

锁定和解锁数据库

强制将缓存区中的数据真正写入后锁住数据库

必须在admin数据库中使用命令

db.runCommand({fsync:1,lock:1}); //类似于node中的fs.fsync

解锁

db.fsyncUnlock();

示例:

打开一个命令行,先锁住

再打开一个命令行,像数据库中写入,会发现

迟迟不返回,说明正在等待写入

但当我们解锁

会发现原本正在等待的数据已经写入

安全措施

  • 物理隔离:电都不插
  • 网络隔离:区域网
  • 防火墙(IP/IP段/白名单/黑名单)
  • 用户名和密码验证

用户管理

要使用户生效,需要在启动服务器时加上--auth

mongod ... --auth

这样我们就不能裸连数据库了,必须要使用账号登录。

查看角色

show roles;

内置角色

  • 数据库用户角色:read、readWrite;
  • 数据库管理角色:dbAdmin、dbOwner、userAdmin
  • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManage;
  • 备份恢复角色:backup、restore
  • 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
  • 超级用户角色:root
  • 内部角色:_system

用户的操作都需要在admin下面进行操作

如果在某个数据库下面执行操作,那么只对当前数据库生效

addUser已经废弃,默认会创建root用户,不安全,不再建议使用

创建用户

针对school数据库可以读

db.createUser({user:'ahhh',pwd:'123',roles:[{db:'school',role:'read'}]});

roles中不加db表示对所有数据库都有权限

显示用户权限

use admin;

var r = db.runCommand({usersInfo:'ahhh',showPrivileges:true})

printjson(r);

修改密码

修改密码

db.changeUserPassword({'ahhh','123456'});

验证密码是否正确

db.auth('ahhh','123456')

添加个人信息

db.runCommand({updateUser:'ahhh',pwd:'123',customData:{name:'ahuang',age:111,telephone:'123123xxx'}});

高级命令

首先runCommand中的参数是一个文档(JSON),但在runCommand中它是具有特殊意义的一些字段。

load(”)

路径分隔符必须使用/而不是\

D:\WEB\database\data //-->错误的

D:/WEB/database/data //-->正确的

group:分组

有以下数据

var stus = [
  {province:'北京',home:'北京',age:1}
  ,{province:'北京',home:'北京',age:2}
  ,{province:'北京',home:'北京',age:3}
  ,{province:'广东',home:'广州',age:1}
  ,{province:'广东',home:'佛山',age:2}
  ,{province:'广东',home:'东莞',age:3}   
]

我们这样执行命令进行分组

db.runCommand({
  group:{
    ns:'students' //namespace
    ,key:{home:1} //按照哪个key分组 可以写很多个
    ,query:{age:{$gt:1}} //满足条件才参与分组
    ,initial:{total:0} //每一组的初始值
    ,$reduce:function(doc,initial){
      initial.total += doc.age; //每个文档累加一次 最终会得到该分组下所有年龄的总和
    }
  }
});

分组结果

//retval:返回值类型说明

{
    "retval" : [
        {
            "home" : "北京",
            "total" : 5
        },
        {
            "home" : "佛山",
            "total" : 2
        },
        {
            "home" : "东莞",
            "total" : 3
        }
    ],
    "count" : NumberLong(4),
    "keys" : NumberLong(3),
    "ok" : 1
}

distinct:查找不重复的key值

以下会在students集合下查找所有key为home的值

db.runCommand({distinct:'students',key:'home'});

返回是这样的

{ "values" : [ "北京", "广州", "佛山", "东莞" ], "ok" : 1 }

执行命令时也可以这样执行

db.runCommand({distinct:'students',key:'home'}).values;

这样能直接得到key的值组成的数组

 [ "北京", "广州", "佛山", "东莞" ]

drop

删除集合除了db.xxx.drop(),也可以

db.runCommand({drop:'students'});

其它

查看数据库信息

db.runCommand({buildInfo:1}); 

查看students集合下上一次的执行错误信息

db.runCommand({getLastError:'students'}); 

固定集合

有着固定大小的集合,满了以后会覆盖掉最先插入的。(先入先出)

特性

  • 没有索引
  • 插入和查询速度非常快,不需要重新分配空间
  • 特别适合存储日志

创建固定集合

  • size单位是kb
  • max单位是
  • capped:是否有上限封顶,必须为true
db.createCollection('logs',{size:5,max:5,capped:true})

非固定集合转换为固定集合

db.runCommand({convertToCapped:'logs',size:5})

gridfs:网格文件存储系统

gridfs是mongodb自带的文件系统,使用二进制存储文件。

mongodb可以以BSON格式保存二进制对象,但是BSON对象的体积不能超过4M。所以mongodb提供了mongofiles。它可以把一个大文件透明地分割成小文件(256k),从而保存大体积的数据

GridFS用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等)

GridFS用两个集合来存储一个文件:fs.files(元信息)与fs.chunks(实际内容)

每个文件的实际内容被存在chunks(二进制数据)中,和文件有关的meta数据(filename,content_type,还有用户自定义的属性)将会被存在files集合中。

使用

存储

将1.txt放到myfiles数据库中

mongofiles -d myfiles put 1.txt

一个文件会在fs.files中对应一个id

假如我们有两份文件存储在gridfs中

可以发现files中有两个id

fs.chunks中则不是这样了,它会分成很多份

查看文件列表

查看myfiles数据库下的所有文件

mongofiles -d myfiles list

详细查看文件信息

db.fs.files.find();

db.fs.files.find(files_id:objectId(''));;

获取&&下载

mongofiles  -d myfile get 1.txt

删除文件

mongofiles -d myfiles delete 1.txt

eval

执行脚本

db.eval('1+1');
<<<
2
db.eval("return 'hello'");
<<<
hello
db.system.js.insert({_id:'xx',value:'111'});
//类似于声明了一个全局变量
db.eval("return xx");
<<<
111

会存储在当前数据库下的Functions文件夹下(和Collections文件夹同级)

db.system.js.insert({_id:'say',value:function(){return 'hello'}});
//类似于声明了一个全局变量
db.eval("say()");
<<<
hello

上一篇:mongoDB基础

未经允许不得转载:ITyet » mongoDB进阶

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
打开看板娘