mongodb基本操作

mongodb基本命令

库级操作命令
表和库 默认都是隐式创建的。可以不用声明
查看库
show dbs;
创建库 直接就可以使用
use shop;
删除库
db.dropDatabase();
查看表
show collections;
创建表 直接就插入数据
db.goods.insert({name:'zhangsan', age:'25'});
删除表
db.goods.drop();

表级别操作命令(CURD  create/update/read/delete)
CURD 操作通常是使用关系型数据库系统中的结构化查询语言(Structured Query Language,SQL)完成的


增 insert 主要针对json格式
db.students.insert({_id:002, name:'xiaoming', age:'28'})
如果没有写 _id, 系统会自动添加一个 _id

删 remove 查询(条件)表达式
db.stu.remove({sn:'001'}); 删除stu表中,sn属性值为 001 的文档
db.stu.remove(); 全部collection删除
dn.stu.remove({sn:'002', true});只删除一行sn属性值为 002 的数据

改 update 新文档替换就文档(相当于替换文档)
update({查谁},{改成什么样},{可选参数})
改谁, 查询表达式
改成什么样。新值或者复制表达式
//修改整个文档
db.stu.update({sn:'001'},{sn:'0001'}); 修改整个文档

//修改文档某一列
$set   修改某列
  db.stu.update({sn:'001'},{$set:{sn:'002'}}); 修改某列的值 
  $unset 删除某列
  $rename 重命名某列
  $inc 增长某列
  $setOnInsert  当upsert为true时。并且发生了insert操作,可以补充的字段
db.stu.update({sn:'004'},{$set:{sn:'0004'}},{$setOnInsert:{gender:'meal'}, {upsert:true}};
/*
db.stu.update({name:'kong'},
{
$set:{name:'king'},   修改
$uset:{jinggu:1}, 删除
$rename:{sex:'gender'}, 重命名
$inc:{age:14} 自增长
})
*/
//第三个参数
//修改时的额外参数
mulit 对符合条件的所有数据产生影响
  注意:就算查询表达式命中多行,也只能改一行。如果要全部修改。使用multi:true 或者mulit:1 全部修改
db.stu.update({name:'zhangsan'},{$set{name:'lisi'}}, {multi:true}); //把全部的张三改成李四
upsert 如果存在符合条件的文档则修改。如果不存在,则添加
db.stu.update({name:'wuyong'}, {$set{name:'junshiwuyong'}}, {upsert:true});

查 find (查询表达式,查询的列)
//查询所有文档所有内容
db.stu.find();  

//查询所有文档的gender属性,(_id属性默认显示)
db.stu.find({},{gender:1}) 

//查询文档的gender属性,并且不显示 _id 属性 
db.stu.find({},{gender:1, _id:0}) 
//查询所有gender为meal的name属性,并且不显示 _id 属性
db.stu.find({gender:'meal'},{name:1, _id:0})

/**
查询表达式详解
*/
1: 基础查询 where的练习:

查出满足以下条件的商品
1.1:主键为32的商品
db.goods.find({goods_id:32});

1.2:不属第3栏目的所有商品($ne)
db.goods.find({cat_id:{$ne:3}},{goods_id:1,cat_id:1,goods_name:1});

1.3:本店价格高于3000元的商品{$gt}
db.goods.find({shop_price:{$gt:3000}},{goods_name:1,shop_price:1});

1.4:本店价格低于或等于100元的商品($lte)
db.goods.find({shop_price:{$lte:100}},{goods_name:1,shop_price:1});

1.5:取出第4栏目或第11栏目的商品($in)
db.goods.find({cat_id:{$in:[4,11]}},{goods_name:1,shop_price:1});

1.6:取出100<=价格<=500的商品($and)
db.goods.find({$and:[{price:{$gt:100},{$price:{$lt:500}}}]);

1.7:取出不属于第3栏目且不属于第11栏目的商品($and $nin和$nor分别实现)
db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]},{goods_name:1,cat_id:1})
db.goods.find({cat_id:{$nin:[3,11]}},{goods_name:1,cat_id:1});
db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{goods_name:1,cat_id:1});

1.8:取出价格大于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}}]}]},{goods_name:1,shop_price:1});

1.9:取出goods_id%5 == 1, 即,1,6,11,..这样的商品
db.goods.find({goods_id:{$mod:[5,1]}});

1.10:取出有age属性的文档
db.stu.find({age:{$exists:1}});
含有age属性的文档将会被查出

/**
游标操作
*/
//可以插入for循环来创建数据
for(var i=0; i<10000; i++){ db.bar.insert({_id:i+1, title:'hello world', content:'aaa'+i})};
想去第几行的时候,可以使用游标操作
游标 是查询的资源或者接口。通过这个接口,可以进行逐条的读取。
1.创建游标
var cursor = db.bar.find(); //把查询结果赋给这个cursor变量
cursor.next(); //向下移动
cursor.hasnext(); //判断是否最后一个
printjson(cursor.next()); //显示

cursor 的 forEach()函数
mycursor.forEach(function(obj){print('your id is '+obj._id)});
cursor 的 skip() 函数 跳过行数
 limit() 函数,取几行
 toArray() 显示结果

游标在分页中的应用
比如,查到10000行,跳过100页取10行
一般,假设每页有n行,当前是page页。
需要跳过(page-1)*n ,再去n行,
在mysql中,使用limit offset N 来实现
在mongo中,只用 skip() 和 limit() 函数实现
跳过9995行
var mycursor = db.bar.find().skip(9995);

查看901页 
var mycursor = db.bar.find().skip(9000).limit(10);
mycursor.forEach(function(obj){printjson(obj)})
或者用toArray()显示  mycursor.toArray();
显示第4个 printjson(mycursor.toArray()[4]);
或者直接 db.bar.find().skip(9000).limit(10);
/**
索引
*/
mysql支持btree索引和hash索引,这个我还没有看。完了看下
mongdb同样也支持btree索引和hash索引


1. 索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引
2. 在mongodb中,索引可以按字段升序/降序来创建,便于排序
3. 默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引

查看查询计划
db.bar.find({id:'99'}).explain(); //查看查询计划

查看索引
db.bar.getIndexes();

创建索引
db.bar.ensureIndex({sn:1}); 1表示正序,-1表示倒叙

删除单个索引
db.bar.dropIndex({filed:1/-1});

一下删除所有索引
db.bar.dropIndexes();

重建索引
一个表经过很多次修改后,导致表的文件产生空洞,索引文件也如此.
可以通过索引的重建,减少索引文件碎片,并提高索引的效率.
类似mysql中的optimize table
db.bar.reIndex();

多列索引
db.bar.ensureIndex({sn:1, name:1});

查找子文档下的内容
db.bar.find({diqu:{shanxi:'changzhi'}})

创建子文档索引
db.bar.ensureIndex({'intro.age':1});

索引性质
普通索引 、 唯一索引 、 稀疏索引 、 哈希索引

唯一索引表示这一列上的数据不能重复
db.teacher.ensureIndex({email:1}, {unique:true});

稀疏索引 
假设file设置了稀疏索引。那么那些不含有file参数的列是不会有稀疏索引的。
默认的索引,会是null。稀疏索引适用于小部分文档含有某列的情况下。
db.teacher.ensureIndex({file:1}, {sparse:true});
如果不包含file对象的话。是不会建立null索引的。

哈希索引(比二叉树还要快很多)
哈希的特性是散落的。查找速度特别快,但是对于某个范围内数据的查找,哈希并没有普通查找快.还有一点是在机械硬盘上哈希不一定好

db.teacher.ensureIndex({file:'hashed'});


/**
mongodb 用户管理


*/
mongodb中,有一个admin数据库,牵扯到服务器层面的,要切换到admin数据库
1: 添加用户
> use admin
> db.addUser(‘sa’,’sa’,false); //false表示只能读,不能写。true表示能读能写

2: 认证//登录
> use test
> db.auth(用户名,密码);

3: 修改用户密码
> use test
> db.changeUserPassword(用户名, 新密码);

3:删除用户
> use test
> db.removeUser(用户名);

/**
mongodb 的导入与导出
*/
Mongodb导出与导入

1: 导入/导出可以操作的是本地的mongodb服务器,也可以是远程的.
所以,都有如下通用选项:
-h host   主机
--port port    端口
-u username 用户名
-p passwd   密码

2: mongoexport 导出json格式的文件

问: 导出哪个库,哪张表,哪几列,哪几行?


-d  库名
-c  表名
-f  field1,field2...列名
-q  查询条件
-o  导出的文件名
-- csv  导出csv格式(便于和传统数据库交换数据)

例:
[root@localhost mongodb]# ./bin/mongoexport -d test -c news -o test.json
connected to: 127.0.0.1
exported 3 records
[root@localhost mongodb]# ls
bin  dump  GNU-AGPL-3.0  README  test.json  THIRD-PARTY-NOTICES
[root@localhost mongodb]# more test.json 
{ "_id" : { "$oid" : "51fc59c9fecc28d8316cfc03" }, "title" : "aaaa" }
{ "_id" : { "$oid" : "51fcaa3c5eed52c903a91837" }, "title" : "today is sataday" }
{ "_id" : { "$oid" : "51fcaa445eed52c903a91838" }, "title" : "ok now" }


例2: 只导出goods_id,goods_name列
./bin/mongoexport -d test -c goods -f goods_id,goods_name -o goods.json

例3: 只导出价格低于1000元的行,并且是csv格式的
./bin/mongoexport -d test -c goods -f goods_id,goods_name,shop_price -q ‘{shop_price:{$lt:200}}’ --csv -o goods.json

注: _id列总是导出
 
Mongoimport 导入

-d 待导入的数据库
-c 待导入的表(不存在会自己创建)
--type  csv/json(默认)
--file 备份文件路径

例1: 导入json
./bin/mongoimport -d test -c goods --file ./goodsall.json

例2: 导入csv  需要声明列的名字
./bin/mongoimport -d test -c goods --type csv -f goods_id,goods_name --file ./goodsall.csv 

//跳过第一行
./bin/mongoimport -d test -c goods --type csv --headline -f goods_id,goods_name --file ./goodsall.csv 

mongodump 导出二进制bson结构的数据及其索引信息(速度比较快!!)
-d  库名
-c  表名
-f  field1,field2...列名
例: 
mongodum -d test  [-c 表名]  默认是导出到mongo下的dump目录

规律: 
1:导出的文件放在以database命名的目录下
2: 每个表导出2个文件,分别是bson结构的数据文件, json的索引信息
3: 如果不声明表名, 导出所有的表

mongorestore 导入二进制文件
例:
 ./bin/mongorestore -d test --directoryperdb dump/test/ (mongodump时的备份目录)

二进制备份,不仅可以备份数据,还可以备份索引, 
备份数据比较小.

/**
replication set 复制集
*/
1.概念。replication set 多套服务器维护相同的数据副本,提高服务器的可用性

//自动配置集群化脚本
vim start.sh //创建一个脚本

脚本内容如下
#!/bin/bash
IP=192.168.1.200
NA=rs2

//清除源文件
pkill -9 mongo  //杀到mongo进程
rm -rf /home/m* //删除遗留文件夹

//创建目录
mkdir -p /home/m17 /home/m18 /home/m19 /home/mlog

//创建复制集
/usr/local/mongodb/bin/mongod --dbpath /home/m17 --logpath /home/mlog/m17.log --port 27017 --fork -smallfiles --replSet ${NA}
//fork 表示后台执行 ${NA} 表示复制集的名字是NA
/usr/local/mongodb/bin/mongod --dbpath /home/m18 --logpath /home/mlog/m18.log --port 27018 --fork -smallfiles --replSet ${NA}
/usr/local/mongodb/bin/mongod --dbpath /home/m19 --logpath /home/mlog/m19.log --port 27019 --fork -smallfiles --replSet ${NA}

//配置
//eof表示中间含有文本操作
/usr/local/mongodb/bin/mongo <<EOF 
use admin 
var rsconf = {
_id:'rs2',
members:[
{_id:0, host:'${IP}:27017'},
{_id:1, host:'${IP}:27018'},
{_id:2, host:'${IP}:27019'}
]
}
rs.initiate(rsconf);
EOF
完毕
我的不成功是因为内存不够!!!!
启动脚本
sh start.sh
//连接17端口
./bin/mongo --port 27017
/**
shard 分片
*/
分片其实就是把数据存在不同的内存上
1:在一台服务器上,分别运行 27017,27018实例, 互为副本集,形成2套repl set
和上边的启动复制集一样,启动17 和18 
mkdir –p /home/m17 /home/18 /home/20 /home/mlog

./bin/mongod --dbpath /home/m17 --logpath/home/mlog/m17/log --fork --port 27017 --smallfiles
./bin/mongod --dbpath /home/m18 --logpath/home/mlog/m18/log --fork --port 27018 --smallfiles

2: 在27020端口上,配置config server
./bin/mongod --dbpath /home/m20 --logpath /home/mlog/m20.log --fork --port 27020 --configsvr

3: 配置mongos,并且和27020建立连接
./bin/mongs --logpath /home/mlog/m30.log --port 30000 --configd 192.168.1.202:27020 --fork 


ps aux|grep mongo  可以查看当前的mongo进程
现在应该有4个进程. 
m17  m18  2个mongo进程(后缀是smallfiles)   
m20 configsvr进程(显示也是mongo进程,后缀是configsvr)
mongos进程(端口是30000,并且已经和27020configsvr绑定在一起了)   

4:连接路由器(然后准备把replset片增加进来)
./bin/mongo --port 30000

5: 添加repl set为片
sh.addShard(‘192.168.1.202:27017’);
sh.addShard(‘192.168.1.202:27018’);

6: 添加待分片的库(填写分片规则)
sh.enableSharding(shop); //接下来要为shop库进行分片
sh.status();  //查看当前状态
sh –help;   //查看帮助文档

7: 添加待分片的表
sh.shardCollection(‘shop.goods’, {goods_id:1}); //把shop下的goods表按照goods_id的规则进行分片

>sh.shardCollection(‘dbName.collectionName’,{field:1});

Field是collection的一个字段,系统将会利用filed的值,来计算应该分到哪一个片上.
这个filed叫”片键”, shard key

mongodb不是从单篇文档的级别,绝对平均的散落在各个片上, 

而是N篇文档,形成一个块"chunk",
优先放在某个片上, 
当这片上的chunk,比另一个片的chunk,区别比较大时, (>=3) ,会把本片上的chunk,移到另一个片上, 以chunk为单位,
维护片之间的数据均衡
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值