mongoDB入门篇
0)mongo :通过客户端连接mongodb数据库
1)show dbs ---显示当前所创建的数据库
2)use test ---创建或切换数据库
3)db.dropDatabase() --删除当前数据库
3)show collections: 显示当前数据库所创建的集合(表)
4)exit:退出mongodb客户端
5)mongodb的安装:
一、Mogodb开篇:基础入门增删改查
MongoDB的优点:
1)内置Sharding:提供基于Range的Auto Sharding机制:一个collection可按照记录的范围,
分成若干个段,切分到不同的Shard上。适当的时候可以无痛的升级
2)支持分布式,性能优越
在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,
而对非索引字段的查询,则是全面胜出。 mysql实际无法胜任大数据量下任意字段的查询,
而mongodb的查询性能实在惊讶。写入性能同样很令人满意,同样写入百万级别的数 据,
基本10分钟以下可以解决
mongodb中有三元素:数据库,集合,文档,其中“集合”,就是对应关系数据库中的“表”,“文档”对应“行”。
下载
上MongoDB官网 ,我们发现有32bit和64bit,这个就要看你系统了,不过这里有两点注意:
①:根据业界规则,偶数为“稳定版”(如:1.6.X,1.8.X),奇数为“开发版”(如:1.7.X,1.9.X),
这两个版本的区别相信大家都知道吧。
②:32bit的mongodb最大只能存放2G的数据,64bit就没有限制
启动
启动之前,我们要给mongodb指定一个文件夹,这里取名为”db",用来存放mongodb的数据
然后运行mongod开启命令,同时用--dbpath指定数据存放地点为“db”文件夹。
例子:mongod --dbpath=e:\mongodb\db
最后要看下是否开启成功,从图中的信息中获知,mongodb采用27017端口,
那么我们就在浏览器里面键入“http://localhost:27017/”
基本操作
由于是开篇,就大概的说下基本的“增删查改“,我们再开一个cmd,输入mongo命令打开shell,
其实这个shell就是mongodb的客户端,同时也是一个js的编译器,默认连接的是“test”数据库
1)insert操作
db.person.insert({"name":"lxg","age":20})
数据库有了,下一步就是集合,这里就取集合名为“person”,要注意的是文档是一个json的扩展(Bson)形式
2)find操作
db.person.find({"name":"lxg"});
我们将数据插入后,肯定是要find出来这里要注意两点:
“_id": 这个字段是数据库默认给我们加的GUID,目的就是保证数据的唯一性
3)update操作
db.person.update({"name":"lxg"},{"name":"wr","age":20})
update方法的第一个参数为“查找的条件”,第二个参数为“更新的值”
4)remove操作
db.person.remove({"name":"lxg"})
remove中如果不带参数将删除所有数据,呵呵,很危险的操作,在mongodb中是一个不可撤回的操作
二、MongoDB第二篇:细说增删改查
1)Insert操作
常见的插入操作也就两种形式存在:“单条插入”和“批量插入”
单条插入
先前也说了,mongo命令打开的是一个javascript shell。所以js的语法在这里面都行得通,
看起来是不是很牛X。
var single={"name":"lxg"}
db.user.insert(single);
2)Find操作
日常开发中,我们玩查询,玩的最多的也就是二类:
①: >, >=, <, <=, !=, =。
②:And,OR,In,NotIn
这些操作在mongodb里面都封装好了,下面就一一介绍:
<1>"$gt", "$gte", "$lt", "$lte", "$ne", "没有特殊关键字"这些跟上面是一一对应的举几个例子
db.user.find({"age":{$lt:22}})
<2> "无关键字“, "$or", "$in","$nin" 同样我也是举几个例子
db.user.find({"name":"lxg","age":20})
db.user.find($or,[{"name":"lxg"},{"name":"wr"}])
db.user.find({"name":{$in:["lxg","wr"]}})
db.user.find({"name":{$nin:["lxg","wr"]}})
<3> 在mongodb中还有一个特殊的匹配,那就是“正则表达式”,这玩意威力很强的
db.user.find({"name":/^j/,"name":/e$/})
<4> 有时查询很复杂,很蛋疼,不过没关系,mongodb给我们祭出了大招,它就是$where,
为什么这么说,是因为$where中的value就是我们非常熟悉,非常热爱的js来助我们一马平川
db.user.find({$where:function(){return this.name ==‘jack‘}})
3)Update操作:更新操作无非也就两种,整体更新和局部更新
我在上一篇使用update的时候,其实那种update是属于整体更新
局部更新:有时候我们仅仅需要更新一个字段,而不是整体更新
① $inc修改器:$inc也就是increase的缩写
db.user.update({"name":"jack"},{$inc:{"age":30}})
② $set修改器
db.user.update({"name":"jack"},{$set:{"age":10}})
<3> upsert操作
这个可是mongodb创造出来的“词”,大家还记得update方法的第一次参数是“查询条件”吗?
那么这个upsert操作就是说:如果没查到,就在数据库里面新增一条,其实这样也有好处,
就是避免了我在数据库里面判断是update还是add操作,使用起来很简单将update的第三
个参数设为true即可
db.user.update({"name":"jack"},{$inc:{"age":1},true}) --如果查询不到就添加一条记录
<4> 批量更新
在mongodb中如果匹配多条,默认的情况下只更新第一条,那么如果我们有需求必须批量更新,
那么在mongodb中实现也是很简单的,在update的第四个参数中设为true即可。例子就不举了
三、Mogodb第三篇:细说高级操作
聚合:常见的聚合操作跟oracle一样,有:count,distinct,group,mapReduce
<1> count:它的使用跟sql里面的使用一样
db.person.count()
db.person.count({"age":20})
<2> distinct:指定了谁,谁就不能重复
db.person.distinct("age")
结果:[20,22,26]
<3> group
在mongodb里面做group操作有点小复杂,不过大家对oracle里面的group比较熟悉的话还是一眼能看的明白的,
其实group操作本质上形成了一种“k-v”模型,就像C#中的Dictionary,好,有了这种思维,
我们来看看如何使用group
下面举的例子就是按照age进行group操作,value为对应age的姓名。下面对这些参数介绍一下:
key: 这个就是分组的key,我们这里是对年龄分组。
initial: 每组都分享一个”初始化函数“,特别注意:是每一组,比如这个的age=20的value的list分享一个
initial函数,age=22同样也分享一个initial函数。
$reduce: 这个函数的第一个参数是当前的文档对象,第二个参数是上一次function操作的累计对象,第一次
为initial中的{”perosn“:[]}。有多少个文档, $reduce就会调用多少次
db.person.group({
"key":{"age":true},
"initial":{"person":[]},
"reduce":function(cur,prev){
prev.person.push(cur.name);
}
})
结果:
[
{"age":20,
"person":[
"lxg",
"wr",
"lisi"
]
},
{"age":22,
"person":[
"jialiu",
"zs"
]
}
]
看到上面的结果,是不是有点感觉,我们通过age查看到了相应的name人员,不过有时我们可能有如下的要求:
①:想过滤掉age>25一些人员。
②:有时person数组里面的人员太多,我想加上一个count属性标明一下。
针对上面的需求,在group里面还是很好办到的,因为group有这么两个可选参数: condition 和 finalize
condition: 这个就是过滤条件。
finalize:这是个函数,每一组文档执行完后,多会触发此方法,那么在每组集合里面加上count也就是它的活了
db.person.group(
{"key":{"age":true},
"initial":{"person":[]},
"reduce":function(doc,out){
out.person.push(doc.name);
},
"finalize":function(out){
out.count=out.person.length;
},
"condition":{"age":{$lt:25}}
})
<4> mapReduce
这玩意算是聚合函数中最复杂的了,不过复杂也好,越复杂就越灵活。
mapReduce其实是一种编程模型,用在分布式计算中,其中有一个“map”函数,一个”reduce“函数
① map:这个称为映射函数里面会调用emit(key,value),集合会按照你指定的key进行映射分组
② reduce:这个称为简化函数,会对map分组后的数据进行分组简化,注意:在
reduce(key,value)中的key就是emit中的key,vlaue为emit分组后的emit(value)的集合,
这里也就是很多{"count":1}的数组
③ mapReduce:这个就是最后执行的函数了,参数为map,reduce和一些可选参数
游标
mongodb里面的游标有点类似我们说的C#里面延迟执行,比如:
var list=db.person.find();
针对这样的操作,list其实并没有获取到person中的文档,而是申明一个“查询结构”,等我们需要的时候通过
for或next()一次性加载过来,然后让游标逐行读取,当我们枚举完了之后,游标销毁,之后我们在通过
list获取时发现没有数据返回了
var list =db.person.find();
list.forEach(function(x){
print(x.name);
})
--上面代码执行完后,你在执行list,发现list中已经没有数据了;
当然我们的“查询构造”还可以搞的复杂点,比如分页,排序都可以加进去
var single=db.person.find().sort({"name",1}).skip(2).limit(2);
那么这样的“查询构造”可以在我们需要执行的时候执行,大大提高了不必要的花销
四、mongoDB第四篇:索引的基本操作
我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,
通常我们又会花费50%的时间在R上面,因为Read操作对用户来说是非常敏感的,处
理不好就会被人唾弃,呵呵.从算法上来说有5种经典的查找,这其中就包括我们今天
所说的“索引查找”,如果大家对oracle比较了解的话,相信索引查找能给我们带来什么
样的性能提升吧。我们首先插入10w数据,上图说话:
db.person.remove()
for(var i=0;i<100000;i++){
var rand=parseInt(i*Math.random());
db.person.insert({"name":"lxg"+i,"age":i});
}
(1)性能分析函数(explain)
好了,数据已经插入成功,既然我们要做分析,肯定要有分析的工具,幸好mongodb中
给我们提供了一个关键字叫做“explain",那么怎么用呢?还是看图,注意,这里的name
字段没有建立任何索引,这里我就查询一个“name10000”的姓名。
db.person.find({"name":"lxg"+10000}).explain()
结果:
{
"cursor":"BasicCursor",
"nscanned":100000,
"nscanedObjects":100000,
"n":1,
"millis":114
}
仔细看红色区域,有几个我们关心的key。
cursor: 这里出现的是”BasicCursor",什么意思呢,就是说这里的查找采用的是“表扫描”,
也就是顺序查找,很悲催啊。
nscanned: 这里是10w,也就是说数据库浏览了10w个文档,很恐怖吧,这样玩让人受不了
n: 这里是1,也就是最终返回了1个文档。
millis: 这个就是我们最最最....关心的东西,总共耗时114毫秒。
(2)建立索引(ensureIndex)
在10w条这么简单的集合中查找一个文档要114毫秒有一点点让人不能接收,好,那么我们
该如何优化呢?mongodb中给我们带来了索引查找,看看能不能让我们的查询一飞冲天.
db.person.ensureIndex({"name":1})
db.person.find({"name":"lxg"+100000}).explain()
结果:
{
"cursor":"BtreeCursor name_1",
"nscanned":1,
"nscannedObjects":1,
"n":1,
"millis":1
"nYields":0
}
这里我们使用了ensureIndex在name上建立了索引。
”1“:表示按照name进行升序,”-1“:表示按照name进行降序。
我的神啊,再来看看这些敏感信息。
cursor: 这里出现的是”BtreeCursor",牛,mongodb采用B树的结构来存放索引,索引名为“name_1"
nscanned: 我擦,数据库只浏览了一个文档就OK了。
n: 直接定位返回。
millis: 看看这个时间真的不敢相信,秒秒杀。
(3)唯一索引
和sqlserver一样可以建立唯一索引,重复的键值自然就不能插入,在mongodb中的使用方法是:
db.person.ensureIndex({"name":1},{"unique":true})
(4)组合索引
有时候我们的查询不是单条件的,可能是多条件,比如查找出生在‘1989-3-2’名字叫‘jack’的同学,
那么我们可以建立“姓名”和"生日“的联合索引来加速查询
db.person.ensureIndex({"name":1,"birthday":1})
db.person.ensureIndex({"birthday":1,"name":1})
看上图,大家或者也知道name跟birthday的不同,建立的索引也不同,升序和降序的顺序不同
都会产生不同的索引,那么我们可以用getIndexes来查看下person集合中到底生成了那些索引。
db.person.getIndexes()
此时我们肯定很好奇,到底查询优化器会使用哪个查询作为操作,呵呵,还是看看效果图
db.person.find({"birthday":"1989-3-2","name":"jack"}).explain()
看完上图我们要相信查询优化器,它给我们做出的选择往往是最优的,因为我们做查询时,查
询优化器会使用我们建立的这些索引来创建查询方案
MongoDB的Hints
如果某一个先执行完则其他查询方案被close掉,这种方案会被mongodb保存起来,
当然如果非要用自己指定的查询方案,这也是可以的,在mongodb中给我们提供
了hint方法让我们可以暴力执行
db.person.find({"birthday":"1989-3-2","name":"jack"})
.hint({"birthday":1,"name":1}).explain()
删除索引
可能随着业务需求的变化,原先建立的索引可能没有必要了,索引会降低CUD这三
种操作的性能,因为idex需要实时维护,所以问题要综合考虑,这里就把刚才建立的索
引清掉来演示一下:dropIndexes的使用
db.person.dropIndexes("name_1")
db.person.dropIndexes("name_1_birthday_1")
db.person.dropIndexes("birthday_1_name_1")
db.person.getIndexes()
五、mongoDB第五篇:JAVA的基本操作
引入jar
org.mongodb.mongo-java-driver
com.google.code.gson.Gson
protected void _insert(Object insertObject){
DBCollection collection=getCollection();
if(collection==null){
return;
}
collection.insert(insertObject);
}
建立SimpleTest.java,完成简单的mongoDB数据库操作
Mongo mongo = new Mongo();
这就创建了一个MongoDB的数据库连接对象,它默认连接到当前机器的localhost地址,端口是27017。
DB db = mongo.getDB(“test”);
这样就获得了一个test的数据库,如mongoDB中没有创建这个数据库也是可以正常运行的,mongoDB可以
在没有创建这个数据库的情况下,完成数据的添加操作,当添加的时候,没有这个库,mongoDB会自动创
建当前数据库。得到了db,下一步我们要获取一个“聚集集合DBCollection”,通过db对象的getCollection
方法来完成。DBCollection users = db.getCollection("users");
这样就获得了一个DBCollection,它相当于我们数据库的“表”。
查询所有数据
DBCursor cur = users.find();
while (cur.hasNext()) {
System.out.println(cur.next());
}
六、相关文档
http://blog.csdn.net/liuzhoulong/article/category/774845
http://book.51cto.com/art/201211/363567.htm
http://www.cnblogs.com/hoojo/archive/2011/06/02/2068665.html --java操作
七、mongoDB最新版本3.0
TJ:唐建法,mongoDB方案架构师
Mongo是拉丁文humongous:巨大,大数据
MongoDB是什么?开源数据库,OLTR定位通用数据库,它灵活的文档
mongoDB总部在美国纽约硅谷
最大特点:
文档模型{JSON},灵活自然的文档
客户端---》服务器---》》数据库,三层之间传递的数据都是json文档模型
维护开发都很方便
高可用的复制集群replicaSet
mongoDB部署时,要求配置集群,至少一主二从
具体使用场景:
1) 数据持久化
2) 读写分离
3) 容灾---》金融行业
水平扩展的分片集群:将数据分为多个片shard,每一个片为一个数据库
具体使用场景:
性能扩展:新一代大数据应用需求,解决高并发量问题
地理位置分布
快速恢复:比如一个项目代表或文件非常大,如果以文件的形式进行复制,复制是相当慢的;如果将其分成多个片进行保存到mongoDB中,回复时就可以用多线程的方式进行恢复;
MongoDB3.0特性
写性能up 7-10%
压缩 30-80%
运维up opsManagers,
3.0引入wiredTiger引擎,无锁的并发控制
2.6之前的版本只有一种存储引擎,之后有多种引擎---》不同引擎有不同的侧重点,根据需求进行选择;如有侧重读的,有侧重写的,还有侧重缓存的。。。
性能指标:并发量和相应延迟
高并发写:是3.0的一大特点;引用场景,物联网应用,比如国外卖车险时,会提供一个客户端软件,插入车上,你的实时信息都会反馈给保险公司,会对你的行为进行分析,若果你安装了,就优惠30%;所以在国外,相同款的车,可能保费相差甚远;这些数据都是实时反馈到大数据中心的;
MongoDB的压缩
默认使用SNAPPY进行压缩,压缩率不高,但速度快
Zlib:压缩率高,用时多些
需要根据需求进行选择
mongoDB使用哪些场景:
异构,半结构/无结构数据,海量数据,高并发量,弱事务
1)异构:比如多套系统要进行合并,各个DB模型都不相同,如何合并能,使用document模型
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。