一: 下载
二:启动
进入命令行:进到mongodb的安装目录
输入 mongod --dbpath=mongodb安装目录中的db目录(刚才自己建立的那个)
——————————————————————————————————————————————————————————————————————————————
mongodb基本操作
——————————————————————————————————————————————————————————————————————————
插入操作:db.person.insert({"name":"jack","age":20})
查找操作
我们将数据插入后,肯定是要find出来,不然插了也白插,这里要注意两点:
db.person.find({"name":"joe"})查单个
db.person.find()查所有
更新操作:
update方法的第一个参数为“查找的条件”,第二个参数为“更新的值”,学过C#,相信还是很好理解的。
db.person.update({"name":"joe"},{"name":"joe","age":30})
删除操作:
remove中如果不带参数将删除所有数据,呵呵,很危险的操作,在mongodb中是一个不可撤回的操作,三思而后行。
db.person.remove({"name":"joe"})删除这个
db.person.remove()删除所有
***************************************************************************************************************************************************************************************
细说增删查改
**********************************************************************************************************************************************************************************
傻眼了,擦,竟然开启不了,仔细观察“划线区域“的信息,发现db文件夹下有一个类似的”lock file”阻止了mongodb的开启,接下来我们要做的就
是干掉它,之后,开启成功,关于mongodb的管理方式将在后续文章分享。
一: Insert操作
可能是“字符串”,可能是“数组”,又有可能是内嵌的一个JSON对象,相同的方式也适合于BSON。
打开命令行:链接客户端
var single={"name":"jack","password":"12345","age":20,"address":{"province":"anhui","city":"hefei"},"favourite":["apple",banana]}
db.user.insert(single)
single.name="joe"
single.age=25
single.address={"province":"jiangsu","city":"nanjiang"}
single.favourite=["money","mm"]
db.user.insert(single)
查看
db.user.find()
出来刚才添加的两个
了跟mongodb内部的批量插入方法,因为该方法是不可或缺的,如果大家非要模拟下批量插入的话,可以自己写了for循环,里面就是insert。
二:Find操作
这些操作在mongodb里面都封装好了,下面就一一介绍:
db.user.find({"age":{$gt:22}})查出来大于22岁的
db.user.find({"age":{$lt:22}})查出来大于22岁的
db.user.find($or:[{"address.province":"anhui"},{"address.province":"jiangsu"}])
db.user.find({address.province:{$in:'["anhui","guangdong"]}})
<4> 有时查询很复杂,很蛋疼,不过没关系,mongodb给我们祭出了大招,它就是$where,为什么这么说,是因为$where中的value
db.user.find({$where:function(){return this.name=='jack'}})
三:Update操作
var
model =db.user.findOne({"name":"jack"})
model.age=30
db.user.update({"name":"jack",model})更新了变量中国保存的model值
<2> 局部更新
没更新前是30
执行 db.user.update({"name":"jack"},{$inc:{"age":30}})年龄增加三十
更新后为六十
② $set修改器
db.user.update({"name":"jack"},{$set:{"age":30}})更新完当前值成为指定的值
<3> upsert操作
没有查到,我就在数据库里面新增一条,其实这样也有好处,就是避免了我在数据库里面判断是update还是add操作,使用起来很简单
将update的第三个参数设为true即可。
db.user.update({"name":"jackson"},{$inc:{"age":30}},true)执行后数据库中多了这条记录
<4> 批量更新
的,在update的第四个参数中设为true即可。例子就不举了。
四: Remove操作
*********************************************************************************************************************************************************************************************************
细说高级操作
**********************************************************************************************************************************************************************************************************
一: 聚合
<1> count
db.person.find()结果为全部数据
db.person.count()结果为全部数据的长度
db.person.count({"age":20})结果为年龄是20岁的人数
<2> distinct
db.person.find()结果为全部数据
db.person.distinct("age")数据为全部的数据的单条记录(一个记录只有一条记录)
<3> group
能看的明白的,其实group操作本质上形成了一种“k-v”模型,就像C#中的Dictionary,好,有了这种思维,
我们来看看如何使用group。
效果图参考:(百度云盘)group图片.png
针对上面的需求,在group里面还是很好办到的,因为group有这么两个可选参数: condition 和 finalize。
效果图参考:(百度云盘)group图片2.png
<4> mapReduce
效果图参考:(百度云盘)group图片3.png
从图中我们可以看到如下信息:
最后我们看一下“collecton”集合里面按姓名分组的情况。
效果图参考:(百度云盘)group图片4.png
二:游标
for或者next()一次性加载过来,然后让游标逐行读取,当我们枚举完了之后,游标销毁,之后我们在通过list获取时,
发现没有数据返回了。
var list=db.person.find();
list.forEach(function(x){
print(x.name);
})
结果:
hxx
hxc
zjl
xx
直接输入list没有数据显示
当然我们的“查询构造”还可以搞的复杂点,比如分页,排序都可以加进去。
var single=db.person.find().sort({"name",1}).skip(2).limit(2);
那么这样的“查询构造”可以在我们需要执行的时候执行,大大提高了不必要的花销。
****************************************************************************************************************************************************************************************
索引操作
****************************************************************************************************************************************************************************************
今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,通常我们
又会花费50%的时间在R上面,因为Read操作对用户来说是非常敏感的,处理不好就会被人唾弃,呵呵。
的话,相信索引查找能给我们带来什么样的性能提升吧。
db.person.remove()
for(var i=0;i<10000;i++){
//(功能为插入一万条数据)
var rand=parseInt(i*Math.random());
db.person.insert({"name":"hxc"+i,"age":i})
}
一:性能分析函数(explain)
好了,数据已经插入成功,既然我们要做分析,肯定要有分析的工具,幸好mongodb中给我们提供了一个关键字叫做“explain",那么怎么用呢?
还是看图,注意,这里的name字段没有建立任何索引,这里我就查询一个“name10000”的姓名。
db.person.find({"name":"hxc"+10000})查找到这个数据
db.person.find({"name":"hxc"+10000}).explain()
使用explain
结果
{
"coursor":"BasincCursor",
"nscanned":10000,
"nscannedObjets":10000,
"n":1,
"millis":114,
........
}
二:建立索引(ensureIndex)
我们带来了索引查找,看看能不能让我们的查询一飞冲天.....
db.person.ensureIndex({"name":1})
//1表示按照name进行升序
db.person.find({"name":"hxc"+10000}).explan()//在此查看与这次查询相关的参数
这里我们使用了ensureIndex在name上建立了索引。”1“:表示按照name进行升序,”-1“:表示按照name进行降序。
我的神啊,再来看看这些敏感信息。
通过这个例子相信大家对索引也有了感官方面的认识了吧。
三:唯一索引
db.person.ensureIndex({"name":1},{"unique":true})。
!!!!!!!!!!再执行姓名相同的数据插入时就报错
四:组合索引
的联合索引来加速查询。
db.person.ensureIndex({"name":1,"birthday":1})
命令行中执行这两句语句
可以实现组合索引
db.person.ensoureIndex({"birthday":1,"name":1})
看到上图,大家或者也知道name跟birthday的不同,建立的索引也不同,升序和降序的顺序不同都会产生不同的索引,
那么我们可以用getindexes来查看下person集合中到底生成了那些索引。
db.person.getIndexs()
此时我们肯定很好奇,到底查询优化器会使用哪个查询作为操作,呵呵,还是看看效果图
看完上图我们要相信查询优化器,它给我们做出的选择往往是最优的,因为我们做查询时,查询优化器会使用我们建立的这些索引来创建查询方案,
如果某一个先执行完则其他查询方案被close掉,这种方案会被mongodb保存起来,当然如果非要用自己指定的查询方案,这也是
可以的,在mongodb中给我们提供了hint方法让我们可以暴力执行。
后面的hint语句内是自己建立的索引
db.person.find({"birthday":"1989-3-2","name":"jack"}).hint({"birthday":1,"name":1}).explain()
五: 删除索引
种操作的性能,因为这玩意需要实时维护,所以啥问题都要综合考虑一下,这里就把刚才建立的索引清空掉来演示一下:dropIndexes的使用。
db.person.dropIndexes("name_1")
db.person.dropIndexes("name_1_birthday_1")
db.person.dropIndexes("birthday_1_name_1")
db.person.getIndexes()
**************************************************************************************************************************************************************************************************
**************************************************************************************************************************************************************************************************
主从复制
如果碰到数据库宕机或者被毁灭性破坏那是多么的糟糕。
2: 从上面的图形中我们可以分析出这种架构有如下的好处:
3:下面我们就一一实践
第一步:我们把mongodb文件夹放在D盘和E盘,模拟放在多服务器上。
第二步:启动D盘上的mongodb,把该数据库指定为主数据库,其实命令很简单:>mongodb --dbpath='XXX' --master,
第三步:同样的方式启动E盘上的mongodb,指定该数据库为从属数据库,命令也很简单,当然我们要换一个端口,比如:8888。
第四步:从图中的红色区域我们发现了一条:“applied 1 operations"这样的语句,并且发生的时间相隔10s,也就说明从属数据库每10s
4:
如果我还想增加一台从属数据库,但是我不想在启动时就指定,而是后期指定,那么mongodb可否做的到呢?答案肯定是可以的。
输入 mongod --dpath=F:\mongodb\db
--port
5555 --slave
看上面的log,提示没有主数据库,没关系,某一天我们良心发现,给他后期补贴一下,哈哈,再开一个cmd窗口,语句也就是
命令行执行如下:
use local
db.sources.insert({"host":"ip地址:端口"})
5: 读写分离
在驱动中给我们提供了一个叫做“slaveOkay"来让我们可以显示的读取从属数据库来减轻主数据库的性能压力,这里就不演示了。
二:副本集
第一步:
既然我们要建立集群,就得取个集群名字,这里就取我们的公司名shopex, --replSet表示让服务器知道集群下还有其他数据库,
mongod --dpaht=d:mongodb\db
--port 2222 --replSet
集群名字/ip:端口
示例:
mongod --dpaht=d:mongodb\db
--port 2222 --replSet shopex/127.0.0.1:3333
第二步:
既然上面说3333是另一个数据库服务器,不要急,现在就来开,这里把E盘的mongodb程序打开。
mongod --dpaht=e:mongodb\db
--port 3333 --replSet shopex/127.0.0.1:2222
第三步:
ok,看看上面的日志红色区域,似乎我们还没有做完,是的,log信息告诉我们要初始化一下“副本集“,既然日志这么说,那我也就
命令行:
mongo
127.0.0.1:2222/admin
db.runCommand({"replSetInitiate":{
"_id":"shopex",
"members":[{"_id":1,"host":"127.0.0.1:2222"},{"_id":1,"host":"127.0.0.1:2222"}
]}})
第四步: 开启成功后,我们要看看谁才能成为主数据库服务器,可以看到端口为2222的已经成为主数据库服务器。
第五步:我们知道sql server里面有一个叫做仲裁服务器,那么mongodb中也是有的,跟sql server一样,仲裁只参与投票选举,这里我们
mongod --dpaht=f:mongodb\db
--port 4444 --replSet shopex/127.0.0.1:2222
然后我们在admin集合中使用rs.addArb()追加即可。
命令行:
mongo 127.0.0.1:2222/admin
rs.addArd("127.0.0.1:4444")
追加好了之后,我们使用rs.status()来查看下集群中的服务器状态,图中我们可以清楚的看到谁是主,还是从,还是仲裁。
不是说该集群有自动故障恢复吗?那么我们就可以来试一下,在2222端口的cmd服务器按Ctrl+C来KO掉该服务器,立马我们发现
在3333端口的从属服务器即可顶上,最后大家也可以再次使用rs.status()来看下集群中服务器的状态。
********************************************************************************************************************************************************************************************************************************
********************************************************************************************************************************************************************************************************************************
在mongodb里面存在另一种集群,就是分片技术,跟sql server的表分区类似,我们知道当数据量达到T级别的时候,我们的磁盘,内存
就吃不消了,针对这样的场景我们该如何应对。
一:分片
下面我对这张图解释一下:
二: 实战
1:开启config服务器
mongod --dpath=c:\mongodb\bin
--port 2222
2: 开启mongos服务器
mongos
--port 3333 --configdb=127.0.0.1:2222
3:启动mongod服务器
e盘: mongod --dpath=e:\mongodb\bin
--port 4444
f盘:
mongod --dpath=f:\mongodb\bin
--port 5555
4: 服务配置
命令行:
mongo 127.0.0.1:3333/admin
db.runCommand({"addshard":"127.0.0.1:4444",allowLocal:true})
回车提示ok
db.runCommand({"addshard":"127.0.0.1:5555",allowLocal:true})
回车提示ok
<2>片已经集群了,但是mongos不知道该如何切分数据,也就是我们先前所说的片键,在mongodb中设置片键要做两步
根据以上的设置
db.runCommand({"enablesharding":"test"})
db.runCommand({"shardcollection":"test.person","key":{"name":1}})
5: 查看效果
好了,至此我们的分片操作全部结束,接下来我们通过mongos向mongodb插入10w记录,然后通过printShardingStatus命令
查看mongodb的数据分片情况。
这里主要看三点信息: