mongodb3.4-配置以及使用

mongodb文档数据库:存储文档(BSON–>JSON二进制)
封装磁盘–>gridfs–>多个BSON(json二进制)–>JS解析器解析成json
特点:内部执行引擎为JS解析器,把文档存储成bson结构,查询时转换为JS对象,并通过熟悉的js语法来操作
与传统数据库区别
传统数据库,结构化数据,定好了表结构后,每一行的内容,必是符合表结构的,就是说列个数类型一样
mongodb:表下的每篇文档都可以有自己独特的结构(json对象都可以有自己独特的属性和值)
场景:影片影评回复打分,传统数据库至少4张表,关系复杂。而文档数据库中,通过一篇文档即可完成

—程序功能解释
mongo:交互终端(客户端)
mongod:服务端,数据库核心进程
mongos:查询路由器,集群时用(数据库分片使用)
mongoexport:导出json,csv,tsv格式
mongoimport:导入json,csv,tsv
mongodump:导出bson
mongorestore:导入bson
bsondump:bson转换json
monoplog:
mongostats:
mongotop:
mongosniff:检查mongo运行状态
mongodb启动后占用空间3-4G,可以用–smallfiles启动,减少启动内存,400M左右

启动服务
mongod –help
mongod -dbpath(数据库存储目录) –logpath(日志存储目录) –fork(后台进程运行,window不支持版本2.X以上) –port(默认27017)
mongod –dbpath G:\MongoDB\data –logpath G:\MongoDB\log\mongodb.log
mongo:连接

常用命令
show databases/dbs;:查看所有数据库
db:查看当前数据库
show tables/collections;:查看当前库下的collection
use databaseName;:选库,也可隐式创建库
db.help():查看帮助
db.createCollection(‘表名’);:创建表,
创建固定集合,大小为100K,文档100,达到文档数量上限时,根据容量清除文档
db.createCollection(‘表名’,{capped:true,size:100,max:100})
db.表名.insert:隐式创建
db.表名.insert({_id:3,name:’haha’,hobby:[‘打篮球’,’羽毛球’]});:插入数据(json格式),不指定id默认自动生成,类似主键
db.表名.insert([{jsonObject},{jsonObject}]:创建多个文档
db.表名.find();:查询表下文档信息
db.表名.drop();:删除表
db.dropDatabase();:删除数据库
db.表名.remove(查询表达式,选项):
查询表达式:匹配属性等于value的所有对象,进行删除
选项(true/false):是否只删除一行,默认false
查询表达式依旧是一个json对象,查询匹配的行将被删除
db.user.remove({})清空表所有
db.表名.remove({_id:1});:删除id含有1的所有文档
db.表名.update(查询表达式,新值or赋值表达式,操作选项);
改谁:查询表达式
改成怎样:新值or赋值表达式
db.user.update({name:’hehe’},{name:’1’});:查询该文档赋予新值
db.user.update({name:’hah’},{set:{name:’heh’}});:查询文档,修改某列值  
            查询文档,修改某列值,删除某列,增长某列  
            db.user.insert({name:’wukong’,sex:’gril’,age:10});  
            db.user.update({name:’wukong’},{$set:{name:'dzsf'},$unset:{sex:0},$inc:{age:16}});  
        操作选项:可选参数  
            multi(true/false):命中多行,默认false修改一行  
                db.user.update({name:’wukong’},{$set:{name:’houzia’}},{multi:true});  
            upsert(true/false):默认false,设置true后,有则修改,没则新增,类似mysql,replace  
                使用
set增加1个字段:db.user.update({name:'wua'},{set:{name:’hah’}},{upsert:true});  
                使用
set增加多个字段:db.user.update({name:'wu'},{set:{name:’hah’,gender:0}},{upsert:true});  
                使用
setOnInsert补充字段:db.user.update({name:'w'},{ set:name:hah,gender:0, setOnInsert:{male:’man’}},{upsert:true});
赋值表达式
set: unset:删除某列,值为数字,字母均可
rename inc:增长某列
$setOnInsert:当upsert为true时,且发生了insert操作,补充里面的字段

db.表名.find(查询表达式,查询的列): 
db.表名.find():查询所有文档
db.user.find({},{name:1,gender:1,_id:0}):查询所有文档,name和gender属性,不查询_id
db.user.find({name:'hah'},{gender:1,_id:0});:查询name为hah文档的gender属性,不查询_id

子文档查询
db.user.insert({name:’zhagnsan’,spc:{area:’taiwan’}});
db.user.find({‘spc.area’:’taiwan’});

查询名字不为wukong的文档{field:{ne:value}}  
    db.user.find({name:{$ne:’wukong’}});  
比较运算符
gt >
gte>= lt <
lte<= ne !=
inin nin not in
all,field:$all:[v1,v2]3000db.user.find(price:$gt:3000);110db.user.find(price:$in:[1,10]);a,bdb.user.insert(hobby:[a,b,c]);db.user.insert(hobby:[a,d,c]);db.user.find(hobby:$all:[a,b]); or or
andand not not
nor>1000<=500price:$gt:1000,price:$lte:500db.user.find($and:[price:$gt:1000,price:$lte:500]);35type:$ne:3,type:$ne:5db.user.find($and:[type:$ne:3,type:$ne:5]);db.user.find(type:$nin:[3,5]);db.user.find($nor:[type:3,type:5]);35>1000<=500$and:[type:$ne:3,type:$ne:5],$and:[price:$gt:1000,price:$lte:500]db.user.find($or:[$and:[type:$ne:3,type:$ne:5],$and:[price:$gt:1000,price:$lte:500]]); exists:某列存在则为真,1存在,0不存在
mod: type:数据为某类型为真,https://docs.mongodb.com/manual/reference/operator/query/type/
取出price%5=1的商品,即1,6,11,16..
db.user.find({price:{mod:[5,1]}});  
    查询存在price列的商品  
        db.user.find({price:{$exists:1}});  
    查询age类型为字符串的商品(注:string为2,double为1)  
        db.user.find({age:{$type:1}});  
js运算符,bson转换json对象然后js引擎处理,效率慢
where:js表达式匹配则为真,db.user.find({where:’this.price>100&&this.price<200’});regex:正则表达式匹配则为真,db.user.find({name:{$regex:/^wukong*/}});

=============游标操作
由于使用js解析,所以可以直接输入js语句
for(var i=0;i<10000;i++){
db.user.insert({sn:i,col1:’aa’+i});
};
声明游标
var cursor=db.user.find({});
cursor.hasNext():判断游标是否到尽头
cursor.next():取出游标的下一个单元
print(cursor.next()):输出bson
printjson(cursor.next()):输出json
while(cursor.hasNext()){printjson(cursor.next());};
一次性获取所有数据,返回数组,缺点会把所有的行立即以对象形式组织在内存中
printjson(cursor.toArray()):看到所有
printjson(cursor.toArray[2]):看到第二行
使用游标迭代函数,处理单元
cursor.forEach(function(obj){printjson(obj);});
游标分作用,skip,limit
跳过9000条,取10条
var cursor=db.user.find({}).skip(9000).limit(10);
db.user.find({}).skip(9000).limit(10):可以直接输出

==================索引
1:提高查询速度,降低写入速度
2:索引可以按照字段升序降序创建,便于排序
3:默认采用btree,2.4之后支持hash索引
db.collection.find({sn:1}).explain():查看查询计划
“stage” : “COLLSCAN”,COLLSCAN表示全表扫描。
“stage” : “IXSCAN”:表示进行的是index scanning。
索引作用类型:单列索引,多列索引,子文档索引
db.user.ensureIndex({sn:1});:添加单列索引,1正序,-1降序
db.user.ensureIndex({sn:1,name:1}):创建多列索引
db.user.ensureIndex({‘spc.area’:1}):子文档索引
db.user.insert({name:’zhagnsan’,spc:{area:’taiwan’}});
db.user.find({‘spc.area’:’taiwan’});
索引性质:普通索引,唯一索引,稀疏索引,hash索引
db.user.ensureIndex({sn:1},{unique:true})
稀疏索引:索引列为空的不创建索引,普通索引则会为null创建索引
db.ter.ensureIndex({email:-1},{sparse:true});
hash索引:不能针对多列创建hash
db.ter.ensureIndex({email:’hashed’});

db.user.getIndexes():查看索引
db.user.dropIndex({sn:1}):删除索引,要指定排序类型
db.user.dropIndexes():删除所有
db.user.reindex():重建索引,减少索引文件碎片,提升效率,类似mysql,optimize table

======================用户管理
牵扯到服务器配置层面的操作,需要先切换到admin数据库,进入超级用户管理模式:use admin
mongo的用户是以数据库为单位建立的,每个数据库有自己的管理员
在设置用户时,需要先在admin数据库下建立一个管理员,这个管理员登陆后,相当于超级管理员
db.createUser({user:”root”,pwd:”root”,roles:[{role:”readWrite”,db:”admin”}]});
登录需要开启权限验证
mongod –dbpath G:\MongoDB\data –logpath G:\MongoDB\log\mongodb.log –auth
权限验证
db.auth(‘root1’, ‘root1’);
db.changeUserPassword(‘root’, ‘root123’);
db.createUser({user:”root1”,pwd:”root1”,roles:[{role:”readWrite”]});
db.dropUser(‘root’);

Built-In Roles(内置角色):
1. 数据库用户角色:read、readWrite;
2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4. 备份恢复角色:backup、restore;
5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
6. 超级用户角色:root
// 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
7. 内部角色:__system
Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限

===========================导入导出
通用选项
-h host
-port port
-u username
-p password

导出,默认json
-d 库名
-c 表名
-f field1,field2…列名
-q 查询表达式,单引号括起来有问题
–csv 导出csv格式
-o 导出文件名
mongoexport -d test -c user -f sn,col1 -q “{sn:{$lte:1000}}” -o ./test.user.json

导入
-d 导入的数据
-c 导入的表(不存在则创建)
–type csv/json(默认)
–file 备份文件路径
–headerline 跳过第一行
mongoimport -d test -c user1 –file ./test.user.json
新版本不需要指定列名,直接跳过第一行即可,第一行的值作为列
mongoimport -d test -c user2 –file ./test.user.csv –type csv –headerline

二进制导入导出,
-d 库名
-c 表名,不声明导出库下所有
-f field1.field2..列名
–dir:备份数据所在位置,例如:/home/mongodump/itcast/
–drop:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,
mongodump:导出2进制bson结构的数据以及json格式索引信息,默认导出到mongo/dump/dbName目录
mongodump -d test -c user1
mongorestore -d test –dir dump/test

======================副本集replication set
是一组保持相同数据集合的mongod实例,其中1个mongod为primary,接受全部写操作,其余secondary负责读操作
primary instance打开oplog,secondary读取oplog,并产生相同数据集
primary和secondary之间相互通信,secondary之间也互相通信,获取对方健康程度,以便当primary宕机时选择谁作为primary
1:创建目录
md r1 r2 r3
2:启动3实例,且声明实例属于某复制集(复制集一致)
mongod –dbpath G:\MongoDB\data\r1 –logpath G:\MongoDB\log\r1\mongodb.log –port 27017 –replSet rs –smallfiles
mongod –dbpath G:\MongoDB\data\r2 –logpath G:\MongoDB\log\r2\mongodb.log –port 27018 –replSet rs –smallfiles
mongod –dbpath G:\MongoDB\data\r3 –logpath G:\MongoDB\log\r3\mongodb.log –port 27019 –replSet rs –smallfiles
3:配置,初始化,第一个默认primary
use admin
var rsconf={
_id:’rs’,
members : [
{
_id:0,
host:’192.168.1.103:27017’
},
{
_id:1,
host:’192.168.1.103:27018’
},
{
_id:2,
host:’192.168.1.103:27019’
}
]
}
rs.initiate(rsconf);
查看状态:rs.status();
删除实例:rs.remove(‘192.168.1.103:27019’);
添加实例::rs.add(‘192.168.1.103:27019’);
在primary添加数据后,在secondary中默认不能读写只和primary通信:rs.slaveOk();
db.shutdownServer():关闭实例,会发现立刻切换到从节点上

===============分片
1:多个mongod
2:一个路由(mongos)
3:configsvr维护meta信息
4:分片规则(configsvr才能维护)

3.4要求配置服务器必须也是副本集
准备数据节点
mongod –dbpath G:\MongoDB\data\r1 –logpath G:\MongoDB\log\r1\mongodb.log –port 27017 –shardsvr –smallfiles
mongod –dbpath G:\MongoDB\data\r2 –logpath G:\MongoDB\log\r2\mongodb.log –port 27018 –shardsvr –smallfiles
启动配置服务器
mongod –dbpath G:\MongoDB\data\r3 –logpath G:\MongoDB\log\r3\mongodb.log –port 27019 –replSet rs –configsvr
mongo –port 27019
var rsconf={
_id:’rs’,
members : [
{
_id:0,
host:’192.168.1.103:27019’
}
]
}
rs.initiate(rsconf);
启动路由
mongos –configdb rs/127.0.0.1:27019 –port 27020 –logpath G:\MongoDB\log\r4\mongodb.log
连接:mongo –port 27020
添加分片
sh.addShard(‘192.168.1.103:27017’)
sh.addShard(‘192.168.1.103:27018’)
查看信息:sh.status();
shop库分片:sh.enableSharding(‘shop’);
shop分片的表,goods_id:利用它计算分到哪一个片上,这个field称为片键,shard key
sh.shardCollection(‘shop.goods’,{goods_id:1});

手动预先分片
mongodb不是从单篇文档的级别绝对平均散落在各个片上.而是N篇文档形成一个”chunk”,
当这个片上的chunk比另一个片的chunk比较大时,会把本片上chunk移到另一个片上,随着数据增多,chunk来回移动增加io
手动预先分片:定义一个规则,N条数据形成一个快,预先分配M个chunk,M个chunk预先分配在不同片上,减少IO操作
sh.shardCollection(‘shop.user’,{userid:1});
预先在1k,2k…40k这样的界限切好chunk,虽然chunk是空的,但会均匀的分配到各个片上
for(var i=0;i<40;i++){sh.splitAt(“shop.user”,{userid:i*1000});}

==============聚合与mapreduce
分组统计:group(),不支持分布式运算
聚合:aggregate(),支持分布式;
统计:mapreduce(),支持分布式;
https://docs.mongodb.com/manual/reference/operator/aggregation/interface/
group:https://docs.mongodb.com/manual/reference/method/db.collection.group/#db.collection.group
db.collection.group({
key:{key1:1,key2:1},分组字段
cond:{},查询条件
reduce:function(curr,result){},聚合函数,curr遍历的每一行,result统计每组信息
initial:{},初始化result
finalize:function(){}统计一组后的回调函数
});

select cat_id,count(cat_id) as cnt from goods where price>50 group by cat_id asc;
    {
    key:{cat_id:1},
    cond:{price>50},
    reduce:function(curr,result){result.cnt+=1;},
    initial:{cnt:0}
    }

select cat_id,sum(goods_number) from goods group by cat_id;
    {
    key:{cat_id:1},
    cond:{},
    reduce:function(curr,result){result.num+=curr.goods_number;},
    initial:{num:0}
    });

select cat_id,max(price) from goods group by cat_id;
    {
    key:{cat_id:1},
    cond:{},
    reduce:function(curr,result){
        if(result.max<curr.price)result.max=curr.price;
    },
    initial:{max:0}
    }

select cat_id,avg(price) from goods group by cat_id;
    {
    key:{cat_id:1},
    cond:{},
    reduce:function(curr,result){
        result.num+=curr.price;
        result.count+=1;
    },
    initial:{num:0,count:0},
    finalize:function(result){
        result.avg=result.num/result.count;
    }
    };

aggregate:
group by grouphaving match
select projectorderby sort
sum sumcount sum
limit limit>50,,,>=35 cat_id去掉表示常量  
    match放在group之前表示where,之后表示having  
    sort:-1表示倒序,1相反  
    db.collection.aggregate([  
        {
match:{price:{gt:50}}},  
        {
group:{_id:"cat_id",total:{sum:1},sum:{ sum:" number"},avg:{ avg:" price”}}},
{match:{total:{gte:3}}},
{sort:{total:1}},  
        {
limit:5}
]);
查询商品总数
db.collection.aggregate([
{group:{_id:null,total:{sum:1}}}
]);

mapreduce:结合shard使用
var map=function(){emit(this.cat_id,this.price);}
var reduce=function(cat_id,values){return Array.avg(values);}
db.goods.mapReduce(map,reduce,{out:’res’});//输出到res表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值