ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 通过配置文件启动mongo服务器 | 参数 |含义 | | --- | --- | |--dbpath | 指定数据库文件存放的目录| |--port | 端口默认是27017 | |--fork | 以后台守护的方式进行启动 | |--logpath | 指定日志文件输出路径| |--config | 指定一个配置文件 | |--auth | 以安全方式启动数据库,需要验证账号和密码| 直接在命令行中通过`mongod --dbpath ...`这样启动服务器,如果参数太多的话,就比较麻烦 So,我们可以选择通过运行配置文件的方式启动服务器 首先,要在一个目录下创建一个`mongo.config`(后缀名无所谓) >[warning] **注意:** 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 ``` 导出的是一个文件 ![](https://box.kancloud.cn/ae43daa34cc45cfd34c582e1ac6aa2ad_592x32.png) 整个文件是一个json ![](https://box.kancloud.cn/e0ab8c1f75ee43b1128e9b5dc04db926_635x80.png) #### 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 ``` 导出来的样子 ![](https://box.kancloud.cn/80c6ab1e477b5426d386243942a50886_493x100.png) (school.dmp文件夹下有一个school文件) #### mongorestore与导入数据库 如果想要导入整个数据库 ``` mongorestore mdmp ``` 如果只想导入其中一个数据库 ``` mongorestore -d school mdmp/school ``` ### 方法三:直接拷贝数据 将整个文件夹拷贝到指定目录下,然后在启动数据库服务器时将其指定为`--dbpath` ## 锁定和解锁数据库 >强制将缓存区中的数据真正写入后锁住数据库 必须在admin数据库中使用命令 ``` db.runCommand({fsync:1,lock:1}); //类似于node中的fs.fsync ``` >解锁 ``` db.fsyncUnlock(); ``` 示例: 打开一个命令行,先锁住 ![](https://box.kancloud.cn/067d3b81b1da8107181d6c17ba54330a_630x98.png) 再打开一个命令行,像数据库中写入,会发现 ![](https://box.kancloud.cn/fa790aafb03078da42b6ab4bd08d6a1a_288x70.png) 迟迟不返回,说明正在等待写入 但当我们解锁 ![](https://box.kancloud.cn/f4520d96008f08a8428f3b64e6d21d65_621x43.png) 会发现原本正在等待的数据已经写入 ![](https://box.kancloud.cn/1640339c4d1e3de2a5ccedf4209d9b63_291x36.png) ## 安全措施 - 物理隔离:电都不插 - 网络隔离:区域网 - 防火墙(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'}); ``` ## 固定集合 有着固定大小的集合,满了以后会覆盖掉最先插入的。(先入先出) ### 特性 - 没有索引 - 插入和查询速度非常快,不需要重新分配空间 - 特别适合存储日志 ### 创建固定集合 ![](http://img.zhufengpeixun.cn/firstinfirstout.png) - 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中 ![](https://box.kancloud.cn/eb3ccc1854805a18e143bc64b1e1da5b_751x94.png) 可以发现files中有两个id 但`fs.chunks`中则不是这样了,它会分成很多份 ![](https://box.kancloud.cn/044661605ba33925376b07df492f1c1f_600x240.png) #### 查看文件列表 查看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文件夹同级) ![](https://box.kancloud.cn/e146da5d4bbb0171548f894a951a3631_371x173.png) ``` db.system.js.insert({_id:'say',value:function(){return 'hello'}}); //类似于声明了一个全局变量 db.eval("say()"); <<< hello ``` ![](https://box.kancloud.cn/faf1f96a01da5d73d71d84501f696817_413x223.png)