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为单位,
维护片之间的数据均衡
MongoDB是一个面向文档的数据库,目前由10gen开发并维护,它的功能丰富,齐全,完全可以替代MySQL。在使用MongoDB产品原型的过程中,我们总结了MonogDB的一些亮点:使用JSON风格语法,易于掌握和理解:MongoDB使用JSON的变种BSON作为内部存储的格式和语法。针对MongoDB的操作都使用JSON风格语法,客户端提交或接收的数据都使用JSON形式来展现。相对于SQL来说,更加直观,容易理解和掌握。Schema-less,支持嵌入子文档:MongoDB是一个Schema-free的文档数据库。一个数据库可以有多个Collection,每个Collection是Documents的集合。Collection和Document和传统数据库的Table和Row并不对等。无需事先定义Collection,随时可以创建。Collection中可以包含具有不同schema的文档记录。 这意味着,你上一条记录中的文档有3个属性,而下一条记录的文档可以有10个属性,属性的类型既可以是基本的数据类型(如数字、字符串、日期等),也可以是数组或者散列,甚至还可以是一个子文档(embed document)。这样,可以实现逆规范化(denormalizing)的数据模型,提高查询的速度。图1 MongoDB是一个Schema-free的文档数据库图2是一个例子,作品和评论可以设计为一个collection,评论作为子文档内嵌在art的comments属性中,评论的回复则作为comment子文档的子文档内嵌于replies属性。按照这种设计模式,只需要按照作品id检索一次,即可获得所有相关的信息了。在MongoDB中,不强调一定对数据进行Normalize ,很多场合都建议De-normalize,开发人员可以扔掉传统关系数据库各种范式的限制,不需要把所有的实体都映射为一个Collection,只需定义最顶级的class。MongoDB的文档模型可以让我们很轻松就能将自己的Object映射到collection中实现存储。图2 MongoDB支持嵌入子文档简单易用的查询方式:MongoDB中的查询让人很舒适,没有SQL难记的语法,直接使用JSON,相当的直观。对不同的开发语言,你可以使用它最基本的数组或散列格式进行查询。配合附加的operator,MongoDB支持范围查询,正则表达式查询,对子文档内属性的查询,可以取代原来大多数任务的SQL查询。CRUD更加简单,支持in-place update:只要定义一个数组,然后传递给MongoDB的insert/update方法就可自动插入或更新;对于更新模式,MongoDB支持一个upsert选项,即:“如果记录存在那么更新,否则插入”。MongoDB的update方法还支持Modifier,通过Modifier可实现在服务端即时更新,省去客户端和服务端的通讯。这些modifer可以让MongoDB具有和Redis、Memcached等KV类似的功能:较之MySQL,MonoDB更加简单快速。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值