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模型

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。