(一).首先 mongodb是非关系型数据库
(1)什么是非关系型数据库呢 ?
通俗的来说就是以文档的形式存储的数据,数据之间没有关系可言
(2)那么它和传统关系型数据库有什么区别呢?
mongodb底层是用js来实现的内部引擎就是js解释器支持js代码
a.传统关系型数据库:保存的是结构化数据,建表时设定好表结构,每一行内容是满足表结构要求的,而每一列的数据类型都是相同的
b.mongo文档型数据库:集合中存储的每篇文档,可以有自己独立的结构,存储的是半结构化数据,(json可以拥有自己独特的属性和值)
c.mongo数据库的collection不用提前创建(可以隐式创建,使用到他而且已经保存数据既可以自动创建)而关系型数据库中的表必须是提前创建的
d.关系型数据库里的表 mongo叫集合 关系型数据库里的行 mongo叫文档
(二)mongodb数据库bin目录下文件的含义-—注意 这里一个exe是一个命令
(1)mongod.exe:指服务端 服务端操作都在该目录下运行 比如创建一个服务 更改端口号等
(2)mongo.exe: 指客户端 客户端操作都在此命令下建库建表存储数据等
(3)mongoexport.exe 数据导出 配合的命令有
导出json格式数据
-d 数据库 -c 集合 -q 查询条件 -f 字段名1,字段名2 -o导出的文件名
mongoexport -d test -c goods -f goods_id,goods_name,shop_price -q {shop_price:{$lt:200}} -o goods.json
导出cvs格式(便于和传统数据库交换数据且excel方便查看)
mongoexport -d shop -c goods -f 字段 -o goods.csv --type csv
(4)mongoimport.exe: 将数据导入
导入json
mongoumport -d text -c goods --file ./goodsall.json
导入csv
mongoimport -d -text -c goods --type csv -f goods_id,goods_name --file ./goodsall.csv
(5)mongodump.exe 导出二进制bson结构数据及其索引信息
mongodump -d text -c 集合名 默认导出到当前文件夹下的dump目录中
注:每个表导出2个文件,分别是bson结构的数据文件, json的索引信息
如果不声明表名, 导出所有的表
(6)mongorestore.exe 导入二进制文件
javascript mongorestore -d shop -c goods --dir ./dump/shop/goods.bson mongorestore -d sh
二进制备份 不仅可以备份数据,还可以备份索引,备份数据小,速度快
(三)mengo入门命令
(1)show dbs 查看当前数据库
(2)use 数据库名 选库
(3)show tables 查看当前库下面的集合
如何隐式创建库表
use 不存在的库名
db.不存在的表名.insert(数据集合) 注意插入数据的情况下就创建的库同时创建了表
(4)删除数据库和集合
db.集合名.drop() //删除集合
db.drop库名() //删除数据库
(四)mongodb基本的增删改查
(1)增:insert()
db.goods.insert([{},{}]) //添加多个文档用[]数组
(2)删:remove()
db.goods.remove({查询集},{justone:true/false}) //参数是指如果多个数据选择删除一个还是多个
(3)改:update()
db.goods.update({查询集},{操作},{参数选项})
如果没写操作就代表整个文档替换
操作1 $set 有就修改 没有就添加
db.goods.update({goods_id:10},{$set:{goods_id:12}})
操作2 $unset 删除集合中的某个字段
db.goods.upset({goods_id:10},{$unset:{cat_id:1}})
操作3 $rename 将字段重命名
db.goods.update({goods_id:10},{$rename:{goods_id:'goods_num'}})
注意新定义的字段要加引号 不加引号认为是一个变量
操作4 $inc 增长某个字段
db.goods.update({name:'ss'},{$inc:{age:-3}})
(4)查询:find()
db.goods.find({查询表达式},{查询的列})
db.goods.find({},{_id:0,goods_name:1}) //0代表该列不显示,1代表该列显示
查询表达式
db.goods.find({goods_id:32}) //商品id为32的商品
db.goods.find({cat_id:{$ne:3}}) //不属于第三栏的所有商品
db.goods.find({shop_price:{$gt:3000}}) //价格大于3000元商品
db.goods.find({shop_price:{$lte:100}}) //价格小于等于100元的商品
db.goods.find({cat_id:{$in:[4,11]}}) //商品栏目在4或者1栏
db.goods.find({hobby:{$exists:1}}) //是否含有hobby字段
db.goods.find().limit(10) //取前十条数据
db.goods.find().skip(10) //跳过10条开始取
db.goods.find().sort({key:1}) //按key升序排列
取出不属于第三栏而且不属于第11栏的商品(用and,and,and,nin,$nor分别实现)
db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]})
db.goods.find({cad_it:{$nin:[3,11]}})
db.goods.find({$nor:[{cat_id:3},{cat_id:11}]})
取出价格大于100小于300,或者大于4000且小于5000的商品
db.goods.find({
$or:[
{
$and:[
{shop_price:{$gt:100}},
{shop_price:{$lt:300}}
]
},
{
$and:[
{shop_price:{$gt:4000}},
{shop_price:{$lt:5000}}
]
}
]
})
(五)mongodb中聚合
db.goods.aggregate([{管道1},{管道2},{管道3}])
mongodb的聚合管道将mengodb文档在一个管道处理完毕后将结果传递给另一个管道处理 其中管道操作是可以重复的
(1)常用管道操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。
$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
db.goods.aggregate([{$group:{_id:'$cat_id',title:{$sum:1}}}]) //查询每个栏目下商品数量
db.goods.aggregate([{$group:{_id:null,title:{$sum:1}}}]) //查询goods下有多少条商品
db.goods.aggregate([{$match:{shop_price:{$gt:50}}},
{$group:{_id:'$cat_id',total:{$sum:'$goods_number'}}}]) //查询每个栏目下的价格大于50的库存量
(六)游标操作
mongo游标就相当于python中的迭代器.将查询结构定义给一个变量,变量就是游标,通过游标我们就可以一个一个获取数据
(1) 游标的声明
var c1 = db.goods.find({查询条件})
(2)游标的操作
a).c1.hasNext() //判断游标是否取到尽头 ,|ture表示取到尽头
b.)c1.next() //取出游标的下一个单元
var mycusor = db.bar.find().limit(5)
print(mycusor.next()) //会显示是一个bson对象的数据
printjson(mycusor.next()) //会显示我们看的懂的数据数组里面套对象
c.)回调函数:cusor.forEach
var gettile = function(obj){print(obj.goods_name)}
var cursor = db.goods.find()
cursor.forEach(gettile)
我们还可以循环打印游标结果:
while(cursor.hasNext()){
printjson(cursor.next())
}
d)游标在分页中的应用
我们假设每页N行,当前是page页,就需要跳过(page-1)*N,再取N行,在mysql中,用limit,offset,N来实现,在MongoDB中,用skip(),limit()函数来实现。
var mycusor = db.bar.find().skip(90).limit(10)//跳过90条,取10条。
(六)索引创建
优化查询的首要考虑的东西就是索引。—降低写入速度。
a.索引提高查询速度,降低写入速度,[权衡常用的查询字段,不必在太多列上建索引]
b.在mongodb中,索引可以按字段升序/降序来创建,便于排序
c.默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引
常用命令:
(1)查看当前索引状态:db.collection.getIndexes()
(2)创建普通单列索引:db.collection.ensureIndex({field:1/-1})//1为正序,-1为逆序
(3)删除单个索引:db.collection.dropIndex({field:1/-1})
(4)删除所有索引:db.collection.dropIndexes()
注意_id所在的列的索引不能删除。
(5)创建多列索引:db.collection.ensureIndex({field1:1/-1,field2:1/-1})
多列索引的使用范围更广,因为一般情况下,我们都是通过多个字段来进行查询数据的,这时候单列索引其实用不到。多列一起建立索引其实就是将两个列绑定到一起,来创建索引
(6)唯一索引的列创建不能重复
db.collection.ensureIndex({field:1/-1},{unique:true})
(7)哈希索引
db.collection.ensureIndex({field:'hashed'})
(七)mongo的复制集 就是mongo的主从复制
一般情况下,我们通常在机器上安装了一个数据库,这是我们的数据都是存在这个数据库中的,如果有一天,因为一些不可控因素导致数据库宕机或者数据库的文件丢失,此时损失就很大了。针对于这种问题,我们希望有一个数据库集,在我们其中一个数据库进行插入的时候,其他数据库也能插入数据,这样其中一台服务器宕机了,也能够使我们的数据正常存取。
创建复制集之前,把所有的mongo服务器都关掉
1、创建三个存储数据库的文件夹,用来保存数据文件 db1/db2/db3
2、打开三个cmd窗口,分别启动三个mongodb:启动三个mongo服务端:分别绑定在27017,27018,27019三个端口。
mongod --dbpath C:\MongoDB\Server\3.4\data\m1 --logpath C:\MongoDB\Server\3.4\data\logs\mongo1.log --port 27017 --replSet rs
mongod --dbpath C:\MongoDB\Server\3.4\data\m2 --logpath C:\MongoDB\Server\3.4\data\logs\mongo2.log --port 27018 --replSet rs
mongod --dbpath C:\MongoDB\Server\3.4\data\m3 --logpath C:\MongoDB\Server\3.4\data\logs\mongo3.log --port 27019 --replSet rs
其中的–replSet就表示创建的数据集的名称,必须指定相同的名称才可以。
3、配置:用客户端连接27017端口的服务器,在这个下面配置\
var rsconf = {
_id:'rs',
members:[
{_id:0,host:'127.0.0.1:27017'},
{_id:1,host:'127.0.0.1:27018'},
{_id:2,host:'127.0.0.1:27019'}
]
}
这时候我们可以打印rsconf来看一下
printjson(rsconf)
接下来需要将配置初始化
rs.initiate(rsconf)
现在我们看到,现在登录客户端已经不是哪台机器,而是rs复制集
我们在主机上插入一条数据,再从机上必须输入rs.slaveOk()之后才能被允许查看数据
在输入rs.status(),可以看到数据集现在又是三个了。
看到比较好的博客详情链接:https://note.youdao.com/ynoteshare1/index.html?id=46dcb0788d9f005392c8b0e4c9e31e4d&type=note
本文全面介绍MongoDB非关系型数据库的特点,包括与传统数据库的区别、基本操作命令、数据导入导出、聚合查询、游标操作、索引创建及复制集配置。适合初学者快速掌握MongoDB的使用。

1447

被折叠的 条评论
为什么被折叠?



