zoukankan      html  css  js  c++  java
  • mongodb进阶

    一、游标

    先插入一张表的数据

    for(i=0; i<100; i++) { db.c.insert({x : i}); }

    定义一个游标

    var cursor = db.c.find();

    以循环的方式输出游标的数据

    while (cursor.hasNext()) { obj = cursor.next(); print(obj.x); }

       

    二 、limit、 skip、sort

    db.c.find().limit(3) 取出前三行

    db.c.find().skip(3) 滤到前三行,

    db.c.find().skip(10).limit(5)11行开始,读出5行。

       

    定义一个游标 并按x列排序,1 表示升序,-1表示降序

    var cursor= db.c.find().skip(10).limit(6).sort({"x":1)});

       

    (一)、用skip实现分页

    n 当skip大量行的时候,会比较慢

    //do not use , slow for large skips

    var page1 = db.foo.find(criteria).limit(100)

    var page1 = db.foo.find(criteria).skip(100).limit(100)

    var page1 = db.foo.find(criteria).skip(200).limit(100)

       

    (二)、技巧

    var page1 = db.foo.find().sort({"date":-1}.limit(100)

    var latest = null

    //display first page

    whill (page1.hasNext(*)){

    last=page1.next();

    display(latest);

    }

    //get the next page

    var page2 = db.foo.find ({"data":("$gt":latest.data}});

    page2.sort({"date":-1}.limit(100)

    这样做就不会存在大量的分页。

     

    (三)、随机抽取文档

       

    db.people.insert({"name" : "joe", "random" : Math.random()})

    db.people.insert({"name" : "john", "random" : Math.random()})

    db.people.insert({"name" : "jim", "random" : Math.random()})

     

    db.people.find()

    var random = Math.random()

    result = db.people.findOne({"random" : {"$gt" : random}})

       

    三、索引

    (一)特点 

    • 可以在任意列上建立索引
    • 索引的构造和使用与传统关系型数据库几乎一样,适用于Oracle的优化技巧也适用于Mongodb
    • 使用索引可以加快查询,但同时会降低修改,插入等的性能
    • 内嵌文档照样可以建立使用索引

      (二) 建立索引

      1、先做一个集合

      db.people.insert([

      { "username" : "smith", "age" : 48, "user_id" : 0 },

      { "username" : "smith", "age" : 30, "user_id" : 1 },

      { "username" : "john", "age" : 36, "user_id" : 2 },

      { "username" : "john", "age" : 18, "user_id" : 3 },

      { "username" : "joe", "age" : 36, "user_id" : 4 },

      { "username" : "john", "age" : 7, "user_id" : 5 },

      { "username" : "simon", "age" : 3, "user_id" : 6 },

      { "username" : "joe", "age" : 27, "user_id" : 7 },

      { "username" : "jacob", "age" : 17, "user_id" : 8 },

      { "username" : "sally", "age" : 52, "user_id" : 9 },

      { "username" : "simon", "age" : 59, "user_id" : 10 }

      ])

         

       2、建立索引

      db.people.ensureIndex({"username" : 1}) //1表示是(正向)升序的索引

      db.people.ensureIndex({"username" : 1,"age":-1}) //建立复合(组合)索引

      explain()函数显示执行计划(执行过程)

      db.people.find().explain()

         

      indexFilterSet: false 显示没有使用索引

      3、查看索引

      查看当前数据库的各集合的索引

      db.system.indexes.find()

      4、删除索引

      db.runCommand({"dropIndexes":"peole","index":"age_1"})

      删除people表中名为age_1的索引

      db.runCommand({"dropIndexes":"peole","index":*})

      删除people表中所有的索引

       四、其他操作

      (一)、聚合

      1、count

      查看数据集合中有多少行

      db.people.count()

      2、distinct

      db.runCommand({"distinct" : "people", "key" : "age"})

      3、group

      分组求和

      db.people.group({

      "key":{"username":true},

      "initial": {"csum": 0 },

      "reduce":function(obj, prev)

      {

      prev.csum += obj.age;

      }

      })

      另外一个例子

         

      doc 是行扫描,prev是记算保存的结果

      (二)、把函数当做key

      To define a grouping function, you must use a $keyf key (instead of "key"). Using "$keyf" makes the group command look something like this:

      db.posts.group({"ns" : "posts",

      "$keyf" : function(x) { return x.category.toLowerCase(); },

      "initializer" :

      })

      "$keyf" allows you can group by arbitrarily complex criteria.

      (三)、MapReduce

      n        与Hadoop的Map-Reduce神似

      n        能完成count、distinct、group所能做的一切事情

      例子:寻找集合中所有的键

      先定义一个map函数

      map = function() { for (var key in this) { emit(key, {count : 1});

      }};

      再定义一个reduce函数

      reduce = function(key, emits) {

      total = 0;

      for (var i in emits) {

      total += emits[i].count;

      }

      return {"count" : total};

      }

      db.runCommand({"mapreduce" : "people", "map" : map, "reduce" : reduce,"out":"result"})

      这个函数的说明 :

      {"mapreduce" : "people"意思是在people这个集合中做mapreduce操作

      "map" : map, "reduce" : reduce,"指明map函数和reduce函数,

      "out":"result" 说明输出到那个集合

      最后可以用 db.result.find()来查看来次操作的结果。

       (四)、冷备份

      关闭mongodb的情况下复制数据目录

      (五)热备份

      mongodump 出来的json和bson这种形式的文件

      mongodump -d db

      -o 重新指定dump文件存放位置

      备份出来的数据还源

      mongorestore -d foo --drop backup/test/

      -d foo 表示还原到foo这个数据库中,

      --drop backup/test/ 表示把原始的的backup/test/删除了。

      (六)、强制一致

      use admin //管理数据库

      db.runCommand({"fsyns":1,"lock":1}) //把缓冲区的数据全部写到硬盘,然后加一把锁,不让数据再写入进来,

      db.$cmd.sys.unlock.findOne();备份完成后解锁。

      (七)、修复数据库

              修复所有数据库:用带—repair参数启动

              db.repairDatabase()

      (八)、GridFS

      mogodb存放超过16M的文件

      n 用于在数据库里存储二进制大文件

      n 可以统一用数据库处理数据,而无需借助外部的文件系统

      n 可以利用MongoDB的复制或分片机制,故障恢复和可扩展性较好

      n 避免使用文件系统的某些限制(例如linux在同一目录下的文件数限制)

      n 避免文件碎片(MongoDB分配空间以2GB作为单位)

      GridFS存放的原理

    • 文件被分成若干块,每个块作为一个文档存储
    • 有一个单独的文档存储分块的信息,以及文件的元数据
    • fs.chunks集合存入具体的数据
    • fs.files集合 存入元数据

         

      五、完成器

      (一)、先完成聚合

      db.posts.group({

      "key" : {"tags" : true},

      "initial" : {"tags" : {}}, //输出的也是tags

      "$reduce" : function(doc, prev) {

      for (i in doc.tags) {

      if (doc.tags[i] in prev.tags) {

      prev.tags[doc.tags[i]]++;

      }else {

      prev.tags[doc.tags[i]] = 1;

      }

      }

      }})

      (二)、再用完成器,确定当天最受欢迎的标签

      "finalize" : function(prev) {

      var mostPopular = 0;

      for (i in prev.tags) {

      if (prev.tags[i] > mostPopular) {

      prev.tag = i;

      mostPopular = prev.tags[i];

      }

      }

      delete prev.tags

      }}})

         

  • 相关阅读:
    简单区分Vmware的三种网络连接模式(bridged、NAT、host-only)
    linux创建账户并自动生成主目录和主目录下的文件
    EF 通用数据层类
    html在线美化网站
    图片在页面中居中显示
    __dopostback的用法
    rdlc报表集锦
    .NET开源免费的功能强大控件库
    使用webclient上传下载实例
    消息队列将并发变串行
  • 原文地址:https://www.cnblogs.com/liuqianli/p/8359271.html
Copyright © 2011-2022 走看看