8天学通MongoDB

文档:https://www.mongodb.org.cn/tutorial/9.html
https://docs.mongodb.com/manual/

菜鸟文档:https://www.runoob.com/mongodb/mongodb-tutorial.html

toc and abstract of fore4days.
<!–
# 8天学通MongoDB

简单入门;简要抄了前四天。后四天高级过了一下,理解没有不知道。反正没有实践过
这几天(2018年3月)掌握了一些简单API的高级操作,主要是操作符的使用;还是和php 搭配
从文章链接可以大概看到发表时间

–>

2017.9.22 星期五 17:24

Ⅰ 基础入门

1 下载

目录结构:mongodb /bin/*.exe GNU-AGPL–3.0 README THIRD-PARTY-NOTICES

2 启动 mongod –path=E:mongodb/db

先建立数据存放文件夹 mongodb/db

3 基本操作

  1. insert

    db.person.insert({"name":"jack","age":20})
    
  2. find

    db.person.find()
    
  3. update

    db.person.update({"name":"jack"},{"name":"joe","age":30})        
    
  4. remove (count)

    db.person.remove()
    db.person.find()
    db.person.count()
    

Ⅱ 细说增删查改

插曲:打不开mongodbl–》干掉“lock file”文件(管理方式中分享)

一 insert操作

JSON BSON

  1. 单条插入
    mongo命令打开的是js shell,所以js语法同。

    var single={.. }       
    db.person.insert(single)
    
  2. 批量插入
    没有提供给shell 这样的方法,可以自己写for循环,里面insert

    二 find操作

  3. $gt $gte $lt $lte $ne 无 ===== >,>=,<,<=,!=,=

    db.mycol.find({"likes":{$lt:50}})
    
  4. 无 $or $in $nin ========and,or,in,notin
  5. 正则
  6. $where

    db.user.find({$where:function(){return this.name=='jack'}})
    

    三 update操作

  7. 整体更新
    update (上一篇的)
  8. 局部更新

    1. $inc increase,没有就创建

      db.user.update({"name":"jack},{$inc:{"age":30}})
      
    2. $set

      db.user.update({"name":"jack},{$set:{"age":30}})
      
  9. upsert操作
    没查到就新增一条,避免 update,add判断。。第三个参数设true

    db.user.update({"name":"jack},{$inc:{"age":30}},true)
    
  10. 批量更新
    第四个参数设为true

四 remove操作

上一篇讲了

Ⅲ 细说高级操作

主要包括:聚合,游标

一 聚合

count distinct group mapReduce

  1. count

    db.person.count()
    db.person.count({"age":20})
    
  2. distinct

    db.person.distinct("age")
    
  3. group
    三个参数
    过滤:两个可选参数:conditon finalize

    db.person.group({
        "key":{"age":true},//分组的key
        "initial":{"person":[]},//每组都分享一个“初始函数”:20一个,22一个
        "$reduce":function(cur,prev){
            //cur当前文档对象,  
            //prev上一次function操作的累计对象,第一次为{"person":[]}。有多少文档,就调用继承
            prev.person.push(cur.name)
        },
        "finalize":function(){
            out.count=out.person.length;
        },
        "condition":{"age":{$lt:25}}
    })
    //输出
    [
        {
            "age":20,
            "person":["jack","mary"],
            "count":2  //可选参数
        },
        {
            "age":22,
            "person":["jack2","mary2","fugui"],
            "count":3   //可选参数
        },
        //过滤后下面的就没有了
        {
            "age":26,
            "person":["jack11","mary"]
        }
    ]
    
  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和一些可选参数。具体看图可知:

      function map(){
         emit(this.name,{count:1});
      } 
      function reduce(key,value){
         var result={count:0};
         for(var i=0;i<value.length;i++){
             result.count+=value[i].count;
         }
         return result;
      }
      
      db.person.mapReduce(map,reduce,{"out":"collection"})
      {
         "result":"collection",//存放的集合名
         "timeMillis":14,//
         "counts":{
             "input":7,//传入文档的个数
             "emit":,7,//此函数被调用的次数
             "reduce":3,//此函数被调用的次数
             "output":4//最后返回文档的个数
         },
         "ok":1,
      }
      //最后我们看一下“collecton”集合里面按姓名分组的情况。
      db.collection.find()
      
      

二 游标

针对这样的操作,list其实并没有获取到person中的文档,
而是申明一个“查询结构”,
等我们需要的时候通过for或者next()一次性加载过来,然后让游标逐行读取,
当我们枚举完了之后,游标销毁,(之后我们在通过list获取时,发现没有数据返回了)

var list=db.person.find();
list.forEach(function(x){
    print(x.name)
})
//逐个输出后
list
//没有数据返回了

当然我们的“查询构造”还可以搞的复杂点,比如分页,排序都可以加进去。
那么这样的“查询构造”可以在我们需要执行的时候执行,大大提高了不必要的花销。

var single=db.person.find().sort({"name",1}).skip(2).limit(2);

Ⅳ 索引操作

CURD,通常我们又会花费50%的时间在R上面

5种经典的查找,包括我们今天所说的“索引查找”

我们首先插入10w数据

一 性能分析函数 explain

仔细看红色区域,有几个我们关心的key:
cursor: 这里出现的是”BasicCursor”,什么意思呢,就是说这里的查找采用的是“表扫描”,也就是顺序查找,很悲催啊。
nscanned: 这里是10w,也就是说数据库浏览了10w个文档,很恐怖吧,这样玩的话让人受不了啊。
n: 这里是1,也就是最终返回了1个文档。
millis: 这个就是我们最最最….关心的东西,总共耗时114毫秒。

db.person.find({"name":"hxc"+1000}).explain()

二 建立索引 ensureIndex

db.person.ensureIndex({"name":1})  //-1降序
db.person.find({"name":"hxc"+1000}).explain()

三 唯一索引

db.person.ensureIndex({"name":1},{"unique":true})
db.person.insert({"name":"hxc","age":20})
db.person.insert({"name":"hxc","age":22})//报错

四 组合索引

  1. 有时候我们的查询不是单条件的,可能是多条件

    db.person.ensureIndex({"name":1,"birthday":1}) 
    db.person.ensureIndex({"birthday":1,"name":1}) 
    

    看到上图,大家或者也知道name跟birthday的不同,建立的索引也不同,升序和降序的顺序不同都会产生不同的索引,

  2. 那么我们可以用getindexes来查看下person集合中到底生成了那些索引。

    db.person.getIndexes()
    
  3. 此时我们肯定很好奇,到底查询优化器会使用哪个查询作为操作,呵呵,还是看看效果图:

    db.person.find({"birthday":"1989-3-2","name":"jack"}).explain()
    

    看完上图我们要相信查询优化器,它给我们做出的选择往往是最优的,因为我们做查询时,查询优化器会使用我们建立的这些索引来创建查询方案,

    如果某一个先执行完则其他查询方案被close掉,这种方案会被mongodb保存起来,

  4. 当然如果非要用自己指定的查询方案,这也是可以的,在mongodb中给我们提供了hint方法让我们可以暴力执行。

    db.person.find({"birthday":"1989-3-2","name":"jack"}).hint({"birthday":"1989-3-2","name":"jack"}).explain()
    

五 删除索引

可能随着业务需求的变化,原先建立的索引可能没有存在的必要了,

(可能有的人想说没必要就没必要呗,)
但是请记住,索引会降低CUD这三种操作的性能,因为这玩意需要实时维护,所以啥问题都要综合考虑一下,这里就把刚才建立的索引清空掉来演示一下:dropIndexes的使用。

db.person.dropIndexes("name_1")

长_天_B#805 2017.9.22五 19:24

章节 学习情况 截止日期 后期安排
noted 前四天noted 2017.9.22 deSituation
coded 后四天coded 2017.9.22 deSituation
八天全 之前过了一遍 2017.9.* ———-
前四天 看了半块 2017.9.22 5 waitToWork
后四天 ——— ——— dework

Ⅴ 主从复制

Ⅵ 分片技术

Ⅶ 运维技术

Ⅷ 驱动实践

knowledge is no pay,reward is kindness
0%