MongoDB学习笔记

MongoDB学习笔记

概念篇


  1. MongoDB 是由C++语言编写的,是一个基于分布式文件存储的、面向文档存储的开源数据库系统。

    • 介于关系型数据库非关系型数据库之间
    • 更偏向于关系型数据库
  2. 数据结构由key/value组成,类似于JSON结构。

  3. MongoDB将数据存放在db目录中。

    • 这个目录应由手工创建在根目录下。
  4. MongoDB不支持多表连接。

  5. MongoDB自动将_id字段设置为主键。

  6. MongoDB的保留数据库:

    • admin:从权限的角度来看,这是”root”数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。
    • local:存储本地数据。
    • config:保存分片信息
  7. MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型。

  8. MongoDB的数据库结构:数据库–>集合(表)–>文档(行)–>字段(列)

  9. MongoDB数据类型:

    数据类型 描述
    String 字符串
    Integer 整数
    Boolean 布尔值
    Double 双精度浮点数
    Array 数组
    Timestamp 时间戳
    Date 日期
    - -
    Object 用于内嵌文档,存储文档对象
    Null 空值
    Symbol 符号(=字符串),用于采用特殊符号的语言
    Object ID 对象ID
    Binary Data 二进制数据
    Code 代码,用于存储JavaScript代码
    Regular Expression 正则表达式
  10. Object ID构成方式:

  • 时间戳 + 机器标识码 + 进程PID + 随机数
  • 如图1所示

CRUD篇


  1. 创建数据库:

    use database_name
       
    • 如果数据库不存在,则创建数据库,否则切换到指定数据库。
    • show dbs:查看所有具有数据的数据库(空数据库除外)
    • db:查看当前数据库
    • MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
  2. 删除数据库:

    db.dropDatabase()
       
    • 删除当前数据库,默认为test。
  3. 删除集合(表):

    // collection为集合名
    db.collection.drop()
       
    • 删除当前数据库下的指定集合
    • 返回值:
      • 成功删除集合,返回true
      • 删除失败,返回false
  4. 创建集合(表):

    // name:集合名,如:"table_01"
    db.createCollection(name, options)
       
    • 在当前数据库中创建name表

    • show tablesshow collections: 查看当前数据库中的所有集合

    • options参数:

      参数 类型 描述
      capped 布尔 如果为 true,则创建固定集合(固定大小的集合)
      size 数值 为固定集合指定一个最大值
      max 数值 指定固定集合中包含文档的最大数量
    • 在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。

  5. 插入文档:

    • 文档的数据结构:BSON(Binary JSON,一种类似 JSON 的二进制形式的存储格式)

      // collection: 集合名;document:数据
      db.collection.insert(document)
      
      // save()在新版本中已废弃
      db.collection.save(document)
      
      /*
       * 3.2版本新增的方法
      */
      // 向集合中插入1个文档
      db.collection.insertOne(
         <document>,
         {
            writeConcern: <document>
         }
      )
      // 向集合中插入1个 / 多个文档 
      db.collection.insertMany(
         [ <document 1> , <document 2>, ... ],
         {
            writeConcern: <document>,
            ordered: <boolean>
         }
      )
         
    • 仅仅是插入数据,若插入数据的主键存在,则抛出org.springframework.dao.DuplicateKeyException

    • 3.2版本新增方法参数说明:

      参数 类型 描述
      document JSON 要插入的文档
      writeConcern Integer 写入策略,默认为 1,即要求确认写操作,0 是不要求。
      ordered Boolean 指定是否按顺序写入,默认 true,按顺序写入。
    • 主键ID自动生成,无需插入。

    • 插入文档时,如果集合不存在,则MongoDB会自动创建集合并把文档插入其中。

    • 定义变量:

      document = ({
         title: 'MongoDB 教程',
         description: 'MongoDB 是一个 Nosql 数据库'
      })
         
  6. 更新文档:

    /* 方法一 */
    db.collection.update(
       <query>,
       <update>,
       {
          upset: <Boolean>,
          multi: <Boolean>,
          writeConcern: <document>
       }
    )
    
    示例:
    db.col.update(
       {'title':'MongoDB 教程'},
       {$set:{'title':'MongoDB'}}
    )
    
    /* 方法二 */
    db.collection.save(
       <document>, 
       {
          writeConcern: <document>
       }
    )
    
    示例:
    db.col.save({
       "_id" : ObjectId("56064f89ade2f21f36b03136"),
       "title" : "MongoDB",
       "description" : "MongoDB 是一个 Nosql 数据库",
       "by" : "Runoob",
       "url" : "http://www.runoob.com",
       "tags" : [
                "mongodb",
                "NoSQL"
       ],
       "likes" : 110
    })
       
    • update()方法参数说明:

      参数 类型 必选 描述
      query 语句 update的查询条件,类似sql update查询内where子句
      update 语句 update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set子句
      upset Boolean upset(= update + insert)如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
      multi Boolean 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
      writeConcern Integer 抛出异常的级别
  7. 删除文档:

    db.collection.remove(
       <query>,
       {
          justOne: <boolean>,
          writeConcern: <document>
       }
    )
    
    // 删除集合里的所有文档
    db.collection.remove({})
       
    • remove()方法的参数:

      参数 类型 必选 描述
      query JSON 删除的文档条件
      justOne Boolean 如果设为 true 或 1,则只删除一个文档,如果不设置该参数或使用默认值 false,则删除所有匹配条件的文档
      writeConcern Integer 抛出异常的级别
    • 删除文档前,先查询文档,避免误删除。

  8. 查询文档:

    /* 方法一: */
    db.collection.find(<query>, <projection>)
    
    /* 方法二: */
    db.collection.findOne()
    
    示例:
    db.collection.find({
          title: "Java教程"
       }, {
          title: 1,
          _id: 0
       }
    )
       
    • find()方法的参数说明:

      参数 类型 必选 描述
      query JSON 使用查询操作符指定查询条件
      projection JSON 使用投影操作符指定返回的键
    • find()方法以非结构化的方式显示所有文档

    • pretty()方法以格式化的方式显示所有文档

      • 使用方法:
        db.collection.find().pretty()
              
    • MongoDB的条件语句查询:

      操作 格式 范例 RDBMS语句
      等于 {:} db.col.find({“by”:”菜鸟教程”}).pretty() where by = ‘菜鸟教程’
      小于 {:{$lt:}} db.col.find({“likes”:{$lt:50}}).pretty() where likes < 50
      小于或等于 {:{$lte:}} db.col.find({“likes”:{$lte:50}}).pretty() where likes <= 50
      大于 {:{$gt:}} db.col.find({“likes”:{$gt:50}}).pretty() where likes > 50
      大于或等于 {:{$gte:}} db.col.find({“likes”:{$gte:50}}).pretty() where likes >= 50
      不等于 {:{$ne:}} db.col.find({“likes”:{$ne:50}}).pretty() where likes != 50
    • And条件:

      • find()方法中的传入多个键,每个键以逗号隔开。
      • 使用方法:
        db.col.find({key1:value1, key2:value2}).pretty()
        
        示例:
        db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()
              
    • Or条件:

      • find()方法中的使用$or关键字作为键
      • 使用方法:
        db.collection.find(
           {
              $or: [
                 {key1: value1},
                 {key2: value2}
              ]
           }
        )
        
        示例:
        db.col.find(
           {
              $or:[
                 {"by":"菜鸟教程"},
                 {"title": "MongoDB 教程"}
              ]
           }
        ).pretty()
              
  9. $type:用来匹配集合中字段的数据类型。

    • 使用方法:
      // 用来匹配集合中title字段类型为String的文档
      db.collection.find({
         "title": {$type: "string"}
      })
         
  10. limit()方法:

    // 读取集合中指定数量的记录
    db.collection.find().limit(<number>)
    
    示例:
    db.col.find({},{"title":1, _id:0}).limit(2)
       
  • limit()方法参数说明:

    参数 类型 必选 描述
    number Integer 读取的记录条数
  1. skip()方法:
    // 跳过集合中指定数量的记录
    db.collection.find().limit(<number>).skip(<number>)
    
    示例:
    db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
       
  • skip()方法的默认参数为0
  1. sort()方法:
    // 根据指定的字段对数据进行排序
    db.collection.find().sort({
       key: 1 / -1
    })
    
    示例:
    db.col.find(
          {}, {
             title: 1,
             _id: 0
          }
       ).sort({
             likes: -1
          }
       )
       
  • sort()方法的参数说明:

    参数 类型 必选 描述
    key String 要排序的字段名
    value Integer 排序方式(1:升序;-1:降序)
  • 排序方式如图2所示。

  1. 索引:
  • 定义:对数据库表中的一列 / 多列的值进行排序的一种结构。

    // 用于在指定的列上创建索引
    db.collection.createIndex(<keys>, <options>)
    
    示例:
    db.collection.createIndex({
       "title": 1, 
       "like": -1
    }, {
       background: true
    })
       
  • createIndex()方法的参数说明:

    参数 类型 必选 描述
    keys JSON 要创建索引的字段(1 为指定按升序创建索引,-1为按降序来创建索引)
    -options JSON 可选参数
    background Boolean 指定以后台方式创建索引,默认为false
    unique Boolean 指定是否创建唯一索引,默认为false
    name String 索引的名称,默认为索引对应的字段名 + 排序顺序
    sparse Boolean 对文档中不存在的字段数据不启用索引(如果启用,则在索引字段中不会查询出没有包含对应字段的文档),默认为false
    expireAfterSeconds Integer 集合的生存时间
    v 索引的版本号
    weights JSON 索引的权重值
    (数值在 1 到 99,999 之间),表示该索引相对于其他索引字段的得分权
    default_language String 决定了停用词及词干和词器的规则的列表
    language_override String 指定了包含在文档中的字段名
  1. 聚合:
    // 用于计算数据,并返回计算后的结果(平均值、求和)
    db.collection.aggregate(<aggregate_operation>)
       
  • 聚合表达式:

    表达式 描述
    $sum 求和
    $avg 求平均值
    $min 求最小值
    $max 求最大值
    - -
    $push 在结果文档中,插入值到一个数组中
    $addToSet 在结果文档中,插入值到一个数组中,但不创建副本
    - -
    $first 获取第1个文档的数据
    $last 获取最后1个文档的数据
  • 聚合管道:

    • 将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。

    • 常用操作:

      操作名称 描述
      $project 修改输入文档的结构
      $match 过滤数据,只输出符合条件的文档
      $limit 限制聚合管道返回的文档数
      $skip 跳过指定数量的文档,并返回剩下的文档
      $unwind 拆分文档中的数组类型字段
      $group 文档分组
      $sort 文档排序
      $geoNear 输出接近某一地理位置的有序文档
    • 示例:

      /* $project示例 */
      db.collection.aggregate({
         $project: {
            _id: 0,  // 输出的文档中不包含_id字段,默认包含
            title: 1,
            author: 1
         }
      })
      
      /* $match示例 */
      // 获取70 < score <= 90的数据,并统计数量
      db.collection.aggregate([
         {
            $match: {score: {$gt: 70}, {$lte: 90}}
         }, {
            $project: {
               _id: 0,
               count: {$sum: 1}
            }
         }
      ]);
            

高级篇


  1. 数据备份:

    // 导出MongoDB所有数据到指定目录中
    mongodump -h(/ --host) <dbhost> -p(/ --port) <portnumber> -d(/ --db) <dbname> -o(/ --out) <backdirectory> -c(/ --collection) <collection>
       
    • mongodump命令参数说明:

      参数 描述
      dbhost MongDB所在服务器地址,例如:127.0.0.1
      portnumber 端口号
      dbname 需要备份的数据库实例名称
      backdirectory 备份的数据存放位置,该目录需要提前建立
      collection 需要备份的集合名称
  2. 数据恢复:

    // 恢复备份的数据
    mongorestore -h(/ --host) <hostname><:port> -d(/ --db) <dbname> <path> --drop 
       
    • mongorestore命令参数说明:
      参数 描述
      –drop 先删除当前数据,然后恢复备份的数据
      path 设置备份数据所在位置
  3. MongoDB监控:

    • mongostat命令:自带的状态检测工具,间隔固定时间获取mongodb的当前运行状态。

      • 使用方法:
        mongostat
              
    • mongotop命令:用来跟踪一个MongoDB的实例,查看哪些时间大量花费在读取和写入数据

      • 使用方法:

        mongotop <sleeptime> --locks
              
      • mongotop命令参数说明:

        参数 类型 必选 描述
        sleeptime Integer 等待的时间长度,以秒为单位
        locks - 报告数据库中每个锁的使用
  4. Java API:

    • 前往MongoDB驱动下载页面下载驱动jar包mongo-java-driver-3.2.2.jar
    • 使用方法:
      // 连接MongoDB服务
      MongoClient mongoClient = new MongoClient("localhost", 27017);
      
      // 连接数据库-getDatabase()
      MongoDatabase database = mongoClient.getDatabase("test");
      
      // 创建集合(表)-createCollection()
      database.createCollection("test");
      
      // 获取集合-getCollection()
      MongeCollection<Document> collection = database.getCollection("test");
      
      // 插入文档-insertMany()
      /** 
      * 1. 创建key-value格式的文档org.bson.Document
      * 2. 创建文档集合List<Document>
      * 3. 将文档插入到集合中
       */
      Document document = new Document("title",  "MongoDB").append("author", "hao3")
      List<Document> documentList = new ArrayList<>();
      documentList.add(document);
      collection.insertMany(documentList);
      
      // 更新文档-updateMany()
      /*  将文档中likes=100的文档修改为likes=200 */
      collection.updateMany(
         Filters.eq("likes", 100), 
         new Document(
            "$set", 
            new Document(
               "likes", 
               200
            )
         )
      );
      
      // 删除文档-remove(), deleteOne(). deleteMany()
      /** 
      * 1. 先用com.mongodb.DBCollection.findOne()方法获取第一个文档。
      * 2. 再使用remove()方法删除 
      */
      /* 删除符合条件的第一个文档 */
      collection.deleteOne(Filters.eq("likes", 200));  
      /* 删除所有符合条件的文档 */
      collection.deleteMany (Filters.eq("likes", 200)); 
      
      //检索文档-find()
      /** 
      * 1. 获取迭代器FindIterable<Document>
      * 2. 获取游标MongoCursor<Document>
      * 3. 通过游标遍历检索出的文档集合
       */
      FindIterable<Document> findIterable = collection.find();  
      MongoCursor<Document> mongoCursor = findIterable.iterator();  
      while(mongoCursor.hasNext()){  
         System.out.println(mongoCursor.next());  
      }  
         

  目录