首页 > 代码库 > MongoDB基础
MongoDB基础
下载 启动 1、启动之前,我们要给mongodb指定一个文件夹,这里取名为”db",用来存放mongodb的数据。 基本操作 由于是开篇,就大概的说下基本的“增删查改“,我们再开一个cmd,输入mongo命令打开shell,其实这个shell就是mongodb的客户端, 【 mongo 】 同时也是一个js的编译器,默认连接的是“test”数据库。
<1> insert 操作 好,数据库有了,下一步就是集合,这里就取集合名为“person”,要注意的就是文档是一个json的扩展(Bson)形式。
<2> find 操作 我们将数据插入后,肯定是要find出来,不然插了也白插,这里要注意两点: ① “_id": 这个字段是数据库默认给我们加的GUID,目的就是保证数据的唯一性。 ② 严格的按照Bson的形式书写文档,不过也没关系,错误提示还是很强大的。
<3> update操作 update方法的第一个参数为“查找的条件”,第二个参数为“更新的值”,学过C#,相信还是很好理解的。
<4> remove操作 remove中如果不带参数将删除所有数据,呵呵,很危险的操作,在mongodb中是一个不可撤回的操作,三思而后行。
一: Insert操作 上一篇也说过,文档是采用“K-V”格式存储的,如果大家对JSON比较熟悉的话,我相信学mongodb是手到擒来,我们知道JSON里面Value 可能是“字符串”,可能是“数组”,又有可能是内嵌的一个JSON对象,相同的方式也适合于BSON。 常见的插入操作也就两种形式存在:“单条插入”和“批量插入”。
① 单条插入 先前也说了,mongo命令打开的是一个javascript shell。所以js的语法在这里面都行得通,看起来是不是很牛X。
② 批量插入 这玩意跟“单条插入”的差异相信大家应该知道,由于mongodb中没有提供给shell的“批量插入方法”,没关系,各个语言的driver都打通 了跟mongodb内部的批量插入方法,因为该方法是不可或缺的,如果大家非要模拟下批量插入的话,可以自己写了for循环,里面就是insert。
二:Find操作 日常开发中,我们玩查询,玩的最多的也就是二类: ①: >, >=, <, <=, !=, =。 ②:And,OR,In,NotIn 这些操作在mongodb里面都封装好了,下面就一一介绍: <1>"$gt", "$gte", "$lt", "$lte", "$ne", "没有特殊关键字",这些跟上面是一一对应的,举几个例子。
<2> "无关键字“, "$or", "$in","$nin" 同样我也是举几个例子
<3> 在mongodb中还有一个特殊的匹配,那就是“正则表达式”,这玩意威力很强的。
<4> 有时查询很复杂,很蛋疼,不过没关系,mongodb给我们祭出了大招,它就是$where,为什么这么说,是因为$where中的value 就是我们非常熟悉,非常热爱的js来助我们一马平川。
三:Update操作 更新操作无非也就两种,整体更新和局部更新,使用场合相信大家也清楚。 <1> 整体更新 不知道大家可还记得,我在上一篇使用update的时候,其实那种update是属于整体更新。
<2> 局部更新 有时候我们仅仅需要更新一个字段,而不是整体更新,那么我们该如何做呢?easy的问题,mongodb中已经给我们提供了两个 修改器: $inc 和 $set。 ① $inc修改器 $inc也就是increase的缩写,学过sql server 的同学应该很熟悉,比如我们做一个在线用户状态记录,每次修改会在原有的基础上 自增$inc指定的值,如果“文档”中没有此key,则会创建key,下面的例子一看就懂。
② $set修改器 啥也不说了,直接上代码
<3> upsert操作 这个可是mongodb创造出来的“词”,大家还记得update方法的第一次参数是“查询条件”吗?,那么这个upsert操作就是说:如果我 没有查到,我就在数据库里面新增一条,其实这样也有好处,就是避免了我在数据库里面判断是update还是add操作,使用起来很简单 将update的第三个参数设为true即可。
<4> 批量更新 在mongodb中如果匹配多条,默认的情况下只更新第一条,那么如果我们有需求必须批量更新,那么在mongodb中实现也是很简单 的,在update的第四个参数中设为true即可。例子就不举了。
四: Remove操作 这个操作在上一篇简单的说过,这里就不赘述了。 今天跟大家分享一下mongodb中比较好玩的知识,主要包括:聚合,游标。 一: 聚合 常见的聚合操作跟sql server一样,有:count,distinct,group,mapReduce。 <1> count count是最简单,最容易,也是最常用的聚合工具,它的使用跟我们C#里面的count使用简直一模一样。
<2> distinct 这个操作相信大家也是非常熟悉的,指定了谁,谁就不能重复,直接上图。
<3> group 在mongodb里面做group操作有点小复杂,不过大家对sql server里面的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就会调用多少次。 看到上面的结果,是不是有点感觉,我们通过age查看到了相应的name人员,不过有时我们可能有如下的要求: ①:想过滤掉age>25一些人员。 ②:有时person数组里面的人员太多,我想加上一个count属性标明一下。 针对上面的需求,在group里面还是很好办到的,因为group有这么两个可选参数: condition 和 finalize。 condition: 这个就是过滤条件。 finalize:这是个函数,每一组文档执行完后,多会触发此方法,那么在每组集合里面加上count也就是它的活了。
<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和一些可选参数。具体看图可知:
从图中我们可以看到如下信息: result: "存放的集合名“; input:传入文档的个数。 emit:此函数被调用的次数。 reduce:此函数被调用的次数。 output:最后返回文档的个数。 最后我们看一下“collecton”集合里面按姓名分组的情况。
二:游标 mongodb里面的游标有点类似我们说的C#里面延迟执行,比如: var list=db.person.find(); 针对这样的操作,list其实并没有获取到person中的文档,而是申明一个“查询结构”,等我们需要的时候通过 for或者next()一次性加载过来,然后让游标逐行读取,当我们枚举完了之后,游标销毁,之后我们在通过list获取时, 发现没有数据返回了。
当然我们的“查询构造”还可以搞的复杂点,比如分页,排序都可以加进去。 var single=db.person.find().sort({"name",1}).skip(2).limit(2); 那么这样的“查询构造”可以在我们需要执行的时候执行,大大提高了不必要的花销。 我们首先插入10w数据,上图说话:
一:性能分析函数(explain) 好了,数据已经插入成功,既然我们要做分析,肯定要有分析的工具,幸好mongodb中给我们提供了一个关键字叫做“explain",那么怎么用呢? 还是看图,注意,这里的name字段没有建立任何索引,这里我就查询一个“name10000”的姓名。
二:建立索引(ensureIndex) 在10w条这么简单的集合中查找一个文档要114毫秒有一点点让人不能接收,好,那么我们该如何优化呢?mongodb中给 我们带来了索引查找,看看能不能让我们的查询一飞冲天.....
这里我们使用了ensureIndex在name上建立了索引。”1“:表示按照name进行升序,”-1“:表示按照name进行降序。
三:唯一索引 和sqlserver一样都可以建立唯一索引,重复的键值自然就不能插入,在mongodb中的使用方法是: db.person.ensureIndex({"name":1},{"unique":true})。
四:组合索引 有时候我们的查询不是单条件的,可能是多条件,比如查找出生在‘1989-3-2’名字叫‘jack’的同学,那么我们可以建立“姓名”和"生日“ 的联合索引来加速查询。 看到上图,大家或者也知道name跟birthday的不同,建立的索引也不同,升序和降序的顺序不同都会产生不同的索引, 那么我们可以用getindexes来查看下person集合中到底生成了那些索引。
五: 删除索引 可能随着业务需求的变化,原先建立的索引可能没有存在的必要了,可能有的人想说没必要就没必要呗,但是请记住,索引会降低CUD这三种操作的性能,因为这玩意需要实时维护,所以啥问题都要综合考虑一下,这里就把刚才建立的索引清空掉来演示一下:dropIndexes的使用。
我之前的文章都是采用console程序来承载,不过在生产环境中这并不是最佳实践,谁也不愿意在机器重启后满地找牙似找mongodb, 在mongodb里面提供了一个叫做“服务寄宿”的模式,我想如果大家对wcf比较熟悉的话很容易听懂。好了,我们实践一下,这里我开一下D盘 里面的mongodb。
这里要注意的有两点: <1> logpath: 当我们使用服务寄宿的时候,用眼睛都能想明白肯定不会用console来承载日志信息了。 <2> install: 开启安装服务寄宿,很happy啊,把管理员的手工操作降低到最小,感谢mongodb。
好了,console程序叫我看log日志,那我就看看,发现mongodb已经提示我们如何开启mongodb,接着我照做就是了。
还要提醒大家一点的就是,这些命令参数很多很复杂也就很容易忘,不过没关系,数据库给我们提供了一个help方法,我们可以 拿mongod和mongo说事。 mongod:
mongo: 备份 这玩意的重要性我想都不需要我来说了吧,这玩意要是搞不好会死人的,mongodb里面常用的手段有3种。 1: 直接copy 这个算是最简单的了,不过要注意一点,在服务器运行的情况下直接copy是很有风险的,可能copy出来时,数据已经遭到 破坏,唯一能保证的就是要暂时关闭下服务器,copy完后重开。 2:mongodump和mongorestore 这个是mongo给我们提供的内置工具,很好用,能保证在不关闭服务器的情况下copy数据。 为了操作方便,我们先删除授权用户。
好了,我们转入正题,这里我先在D盘建立一个backup文件夹用于存放test数据库。 快看,数据已经备份过来了,太爽了,现在我们用mongorestore恢复过去,记住啊,它是不用关闭机器的。 提一点的就是 drop选项,这里是说我将test数据恢复之前先删除原有数据库里面的数据,同样大家可以通过help查看。
------------------
Mongodb数据库的新建与删除(在cmd中的操作)
|
MongoDB基础