MongoDB---介于关系数据库和非关系型数据库之间
基于分布式文件存储的数据库,为web应用提供可扩展的高性能数据库存储解决方案
将数据库存储为一个文档(类似于JSON对象),数据结构由键值对组成
支持查询表达,可以设置任何属性的索引,支持副本集,分片
搭建MongoDB服务器
装包 mongodb-linux-x86_64-rhel70-3.6.3.tgz(免安装,解压后可直接运行)
[root@mongodb50 ~]# tar -zxf mongodb-linux-x86_64-rhel70-3.6.3.tgz
[root@mongodb50 ~]#ls
mongodb-linux-x86_64-rhel70-3.6.3
mongodb-linux-x86_64-rhel70-3.6.3.tgz
...
配置文件
[root@mongo50 ~]# mkdir /usr/local/mongodb
[root@mongo50 ~]# cd /usr/local/mongodb
[root@mongo50 mongodb]# mkdir -p data/db log etc
//创建存放数据库目录,日志,配置文件的目录
[root@mongodb50 mongodb]# cp -r /root/mongodb/mongodb-linux-x86_64-rhel70-3.6.3/bin/ . //拷贝bin文件到当前目录
[root@mongodb50 mongodb]# ls
bin data etc log
[root@mongodb50 mongodb]# vim etc/mongodb.conf
fork=true //服务以守护进程的方式运行
dbpath=/usr/local/mongodb/data/db/ //指定数据库目录
logpath=/usr/local/mongodb/log/mongodb.log //指定日志文件
logappend=true //以追加的方式记录日志信息
启动服务
[root@mongo50 mongodb]# /usr/local/mongodb/bin/mongod --help //查看帮助
[root@mongo50 mongodb]# bin/mongod -f /usr/local/mongodb/etc/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 3217
child process started successfully, parent exiting
[root@mongo50 mongodb]#netstat -pntul | grep mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 3217/mongod
[root@mongo50 mongodb]# bin/mongod -f /usr/local/mongodb/etc/mongodb.conf --shutdown //停止服务
链接服务
[root@mysql50 mongondb]# /usr/local/mongodb/bin/mongo
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
...
> help //查看帮助
db.help() help on db methods
db.mycoll.help() help on collection methods
...
> show dbs //查看已有的库
admin 0.000GB
config 0.000GB
local 0.000GB
指定端口和IP,定义启动/停止别名,便于操作
[root@mongo50 mongodb]# bin/mongod -f /usr/local/mongodb/etc/mongodb.conf --shutdown
[root@mongodb50 mongodb]# vim etc/mongodb.conf
fork=true
dbpath=/usr/local/mongodb/data/db/
logpath=/usr/local/mongodb/log/mongodb.log
logappend=true
bind_id=192.168.4.50
port=27050
[root@mongo50 mongodb]# vim /root/.bashrc
...
alias mongo='/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/etc/mongodb.conf'
alias mongos='/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/etc/mongodb.conf --shutdown'
...
[root@mongodb50 mongodb]#mongo
about to fork child process, waiting until server is ready for connections.
forked process: 3550
child process started successfully, parent exiting
[root@mongo50 mongodb]# netstat -pntul | grep mongo
tcp 0 0 192.168.4.50:27050 0.0.0.0:* LISTEN 3550/mongod
[root@mongo50 mongodb]# /usr/local/mongodb/bin/mongo --host 192.168.4.50 --port 27050
MongoDB shell version v3.6.3
connecting to: mongodb://192.168.4.50:27050/
...
常用管理命令
show dbs | 查看已有的库 |
db | 显示当前所在的库 |
use 库名 | 切换库,若库不存在延时创建库 |
show collections或show tables | 查看库下已有集合 |
db.dropDatabase | 删除当前所在的库 |
db.集合名.drop() | 删除集合 |
db.集合名.save({‘’,‘’}) | 创建集合,集合不存在,创建并添加文档 |
db.集合名.find() | 查看文档 |
db.集合名.count() | 统计文档 |
db.集合名.insert({"名字":"值","..":".."}) | 插入记录 |
db.集合名.find(条件) | 按条件查找 |
db.集合名.findOne() | 返回查询一条文档 |
db.集合名.remove({}) | 删除所有文档 |
db.集合名.remove({条件}) | 删除与 条件匹配的所有文档 |
>show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> use lianxi
switched to db lianxi
> db
lianxi
> db.study.save({'name':'bob','id':'123'})
WriteResult({ "nInserted" : 1 })
> show collections
study
> db.study.find()
{ "_id" : ObjectId("5c21cd5c40f6f036ad6e7d88"), "name" : "bob", "id" : "123" }
> db.study.remove({})
WriteResult({ "nRemoved" : 1 })
> db.study.drop()
true
基本数据类型
字符串string | UTF-8字符串都可以表示为字符串类型的数据 {name:"水月"}或{school:"qinghua"} |
布尔bool | 值为true 和 false {x:false} |
空null | 用于表示空值或者不存在的字段 {y:null} |
数值 | shell默认使用64位浮点型数值 {x:3.14} NumberInt(4字节整数,小数只存整数部分) NumberLong(8字节整数,只能存整数) {z:NumberLong(3)} |
数组array | 数据列表或数据集可以表示为数组{d:["a","b","c"]} |
代码 | 查询和文档中可以包括任何JavaScript代码 {x:function(){/* 代码*/}} |
日期 | 日期被存储为自新纪元1970年以来经过的毫秒数,不含时区 {x:new Date()} |
对象 | 对象id是一个12字节的字符串,是文档的唯一标识 {x:ObjectId()},默认自动生成 |
内嵌 | 文档可以嵌套其他文档,被嵌套的文档作为值来处理 |
正则表达式 | 查询时,使用正则表达式作为限定条件 {n:/正则表达式/} |
字符串,布尔,空,数值,数组演示
> db.study.save({name:"水月",card:true,school:"qinghua",score:99.88,history:NumberInt(97.8),maths:NumberLong(100),hobby:["basketball","roller-skating","film","music"]})
WriteResult({ "nInserted" : 1 })
> db.study.find()
{ "_id" : ObjectId("5c21d51040f6f036ad6e7d89"), "name" : "水月", "card" : true, "school" : "qinghua", "score" : 99.88, "history" : 97, "maths" : NumberLong(100), "hobby" : [ "basketball", "roller-skating", "film", "music" ] }
代码,日期,对象,内嵌,正则演示
> db.learn.find()
{ "_id" : ObjectId("5c21df8140f6f036ad6e7d8a"), "lname" : "php", "code" : { "code" : "function (){/* <?php echo \"hello boy!\"?> */}" }, "time" : ISODate("2018-12-25T07:42:57.765Z") }
> db.success.save({resume:{name:"haryPoter",school:"Hogwarts",like:"magic"}})
WriteResult({ "nInserted" : 1 })
> db.success.find()
{ "_id" : ObjectId("5c21e0ec40f6f036ad6e7d8b"), "resume" : { "name" : "haryPoter", "school" : "Hogwarts", "like" : "magic" } }
> db.success.save({code:/abc$/})
WriteResult({ "nInserted" : 1 })
> db.success.find()
{ "_id" : ObjectId("5c21e0ec40f6f036ad6e7d8b"), "resume" : { "name" : "haryPoter", "school" : "Hogwarts", "like" : "magic" } }
{ "_id" : ObjectId("5c21e21440f6f036ad6e7d8c"), "code" : /abc$/ }
数据导入或导出
数据导出
mongoexport [--host IP地址 --port 端口] -d 库名 -c 集合名 -f 字段名,字段名 --type=csv > 目录名/文件名.csv
csv格式必须写字段
mongoexport --host IP地址 --port 端口 -d 库名 -c 集合名 -f 字段名,字段名 -q ‘{条件}’ --type=csv > 目录名/文件名.csv
mongoexport [--host IP地址 --port 端口] -d 库名 -c 集合名 -[q '{条件}' -f 字段列表 ] --type=json > 目录名/文件名.json
[root@mongo50 mongodb]# bin/mongoexport --host 192.168.4.50 --port 27050 -d lianxi -c success --type=csv -f resume,code
2018-12-25T16:16:45.127+0800 connected to: 192.168.4.50:27050
resume,code
"{""name"":""haryPoter"",""school"":""Hogwarts"",""like"":""magic""}",
,/abc$/
2018-12-25T16:16:45.128+0800 exported 2 records
[root@mongo50 mongodb]# bin/mongoexport --host 192.168.4.50 --port 27050 -d lianxi -c success --type=json > dbbak.json2018-12-25T16:30:24.066+0800 connected to: 192.168.4.50:27050
2018-12-25T16:30:24.067+0800 exported 2 records
[root@mongo50 mongodb]# cat dbbak.json
{"_id":{"$oid":"5c21e0ec40f6f036ad6e7d8b"},"resume":{"name":"haryPoter","school":"Hogwarts","like":"magic"}}
{"_id":{"$oid":"5c21e21440f6f036ad6e7d8c"},"code":{"$regex":"abc$","$options":""}}
数据导入
mongoimport --host IP地址 --port 端口 -d 库名 -c 集合名 --type=json 目录名/文件名.json
表里需要没有数据,不然导入不成功
[root@mongo50 mongodb]# bin/mongoimport --host 192.168.4.50 --port 27050 -d lianxi -c success --type=json dbbak.json //已经存在,导入失败
2018-12-25T16:34:23.143+0800 connected to: 192.168.4.50:27050
2018-12-25T16:34:23.144+0800 num failures: 2
2018-12-25T16:34:23.144+0800 error inserting documents: multiple errors in bulk operation:
- E11000 duplicate key error collection: lianxi.success index: _id_ dup key: { : ObjectId('5c21e0ec40f6f036ad6e7d8b') }
- E11000 duplicate key error collection: lianxi.success index: _id_ dup key: { : ObjectId('5c21e21440f6f036ad6e7d8c') }
2018-12-25T16:34:23.144+0800 imported 0 documents
[root@mongo50 mongodb]# bin/mongoimport --host 192.168.4.50 --port 27050 -d lianxi1 -c success --type=json dbbak.json //重新定义库名lianxi1
2018-12-25T16:35:55.607+0800 connected to: 192.168.4.50:27050
2018-12-25T16:35:55.802+0800 imported 2 documents
[root@mongo50 mongodb]# bin/mongo -host 192.168.4.50 -port 27050
> show dbs
admin 0.000GB
config 0.000GB
lianxi 0.000GB
lianxi1 0.000GB
local 0.000GB
switched to db lianxi1
> show tables
success
> db.success.find()
{ "_id" : ObjectId("5c21e0ec40f6f036ad6e7d8b"), "resume" : { "name" : "haryPoter", "school" : "Hogwarts", "like" : "magic" } }
{ "_id" : ObjectId("5c21e21440f6f036ad6e7d8c"), "code" : /abc$/ }
mongoimport --host IP地址 --port 端口 -d 库名 -c 集合名 --type=csv [--headline/ -f 文档列表名 ] [--drop] 目录名/文件名.csv
导入数据时,若库和集合不存在,则先创建库和集合再导入数据。若存在,则以追加方式导入数据到集合里
使用--drop 选项可以删除源数据后导入新数据,--headerline 忽略标题 不能和-f 同时存在
> db.csv.save({name:"bob",sex:"m",hobby:"book"})
WriteResult({ "nInserted" : 1 })
> show tables;
csv
success
[root@mongo50 mongodb]# bin/mongoexport --host 192.168.4.50 --port 27050 -d lianxi1 -c csv --type csv -f name,sex,hobby > csvbak.csv
2018-12-25T16:59:51.958+0800 connected to: 192.168.4.50:27050
2018-12-25T16:59:51.959+0800 exported 1 record
[root@mongo50 mongondb]# cat csvbak.csv
name,sex,hobby
bob,m,book
[root@mongo50 mongodb]# bin/mongoimport --host 192.168.4.50 --port 27050 -d lianxi1 -c csv --type csv -f name,sex,hobby csvbak.csv
2018-12-25T17:05:26.782+0800 connected to: 192.168.4.50:27050
2018-12-25T17:05:26.783+0800 imported 2 documents
> db.csv.find() //以追加的方式导入,并且包括了标题
{ "_id" : ObjectId("5c21f0abc24bdbea7b8ce8c7"), "name" : "bob", "sex" : "m", "hobby" : "book" }
{ "_id" : ObjectId("5c21f2d6af1ef5d24b56fcb3"), "name" : "name", "sex" : "sex", "hobby" : "hobby" }
{ "_id" : ObjectId("5c21f2d6af1ef5d24b56fcb4"), "name" : "bob", "sex" : "m", "hobby" : "book" }
[root@mongo50 mongodb]# bin/mongoimport --host 192.168.4.50 --port 27050 -d lianxi1 -c csv --type csv --headerline csvbak.csv //忽略标题的导入
2018-12-25T17:11:02.306+0800 connected to: 192.168.4.50:27050
2018-12-25T17:11:02.307+0800 imported 1 document
> db.csv.find()
{ "_id" : ObjectId("5c21f0abc24bdbea7b8ce8c7"), "name" : "bob", "sex" : "m", "hobby" : "book" }
{ "_id" : ObjectId("5c21f2d6af1ef5d24b56fcb3"), "name" : "name", "sex" : "sex", "hobby" : "hobby" }
{ "_id" : ObjectId("5c21f2d6af1ef5d24b56fcb4"), "name" : "bob", "sex" : "m", "hobby" : "book" }
{ "_id" : ObjectId("5c21f426af1ef5d24b56fcc0"), "name" : "bob", "sex" : "m", "hobby" : "book" }
[root@mongo50 mongodb]# bin/mongoimport --host 192.168.4.50 --port 27050 -d lianxi1 -c csv --type csv --headerline --drop csvbak.csv //忽略标题行,并且删除之前已有数据
2018-12-25T17:12:32.459+0800 connected to: 192.168.4.50:27050
2018-12-25T17:12:32.459+0800 dropping: lianxi1.csv
2018-12-25T17:12:32.647+0800 imported 1 document
> db.csv.find()
{ "_id" : ObjectId("5c21f480af1ef5d24b56fcca"), "name" : "bob", "sex" : "m", "hobby" : "book" }
比如,把/etc/passwd 文件中的内容导入到mongodb中(这里以csv形式导入)
[root@mongo50 mongodb]# cp /etc/passwd userdb
[root@mongo50 mongodb]# ls
bin csvbak.csv data dbbak.json etc log userdb
[root@mongo50 mongodb]#sed -i 's/:/,/g' userdb //因为数据库是以,号分隔,所以将分隔符改为,
[root@mongo50 mongodb]# sed -i '1iname,pass,uid,gid,comment,hmdir,shell' userdb
//定义字段名
[root@mongo50 mongodb]# bin/mongoimport --host 192.168.4.50 --port 27050 -d userdb -c user --headerline --type=csv userdb
2018-12-25T17:27:48.996+0800 connected to: 192.168.4.50:27050
2018-12-25T17:27:49.125+0800 imported 41 documents
[root@mongo50 mongodb]#bin/mongo -host 192.168.4.50 -port 27050
> show dbs
admin 0.000GB
...
local 0.000GB
userdb 0.000GB
> use userdb
switched to db userdb
> show tables
user
> db.user.find()
{ "_id" : ObjectId("5c21f814af1ef5d24b56fcd5"), "name" : "root", "pass" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "hmdir" : "/root", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5c21f814af1ef5d24b56fcd6"), "name" : "bin", "pass" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "hmdir" : "/bin", "shell" : "/sbin/nologin" }
...
Type "it" for more //默认显示20行,安it继续浏览
> it
{ "_id" : ObjectId("5c21f814af1ef5d24b56fce9"), "name" : "abrt", "pass" : "x", "uid" : 173, "gid" : 173, "comment" : "", "hmdir" : "/etc/abrt", "shell" : "/sbin/nologin" }
...
数据备份
mongodump [--host 地址 --port 端口] //备份数据所有库到当前目录下的dump下(文件默认以库名方式备份)
mongodump [--host 地址 --port 端口] -d 数据库名 -c 集合名 -o 目录
bsondump ./dump/文件名/数据文档.bson
[root@mongo50 mongodb]# bin/mongodump --host 192.168.4.50 --port 27050 -d userdb
2018-12-25T17:47:35.747+0800 writing userdb.user to
2018-12-25T17:47:35.748+0800 done dumping userdb.user (41 documents)
[root@mmongo50 mongodb]# ls
bin csvbak.csv data dbbak.json dump etc log userdb
[root@mongo50 mongodb]# cd dump/
[root@mysql50 dump]# ls
userdb
[root@mongo50 mongodb]#bin/mongodump --host 192.168.4.50 --port 27050 -d userdb -o userdbbak
2018-12-25T17:46:30.973+0800 writing userdb.user to
2018-12-25T17:46:30.974+0800 done dumping userdb.user (41 documents)
[root@mongo50 mongodb]#ls
bin csvbak.csv data dbbak.json etc log userdb userdbbak
[root@mongo50 mongodb]#bin/bsondump userdbbak/userdb/user.bson
{"_id":{"$oid":"5c21f814af1ef5d24b56fcd5"},"name":"root","pass":"x","uid":0,"gid":0,"comment":"root","hmdir":"/root","shell":"/bin/bash"}
...
数据恢复
mongorestore --host IP地址 --port 端口 -d 数据库名 [ -c 集合名 ] 备份目录名