Node学习笔记 Mongodb 和 Mongoose

关系型数据库 和 非关系型数据库

  • 关系型数据库

    • 最典型的数据结构是表
    • 关系型数据库是由二维表及其之间的联系所组成的一个数据组织
    • 都需要使用 SQL 语言操作
    • ……
  • 非关系型数据库

    • 严格上不是一种数据库,没有 的概念,是一种数据结构化存储方法的集合
    • 数据结构由键值 (key => value) 对组成,类似于 JSON 对象
    • 在非关系型数据库中,集合 相当于 文档对象 相当于 表记录
    • ……

MongoDB

介绍

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

安装

安装文件下载地址:[https://www.mongodb.com/download-center/community]

Windows 平台安装 MongoDB:https://www.runoob.com/mongodb/mongodb-window-install.html

在安装过程中需要特别注意,需要将 Install MongoDB Compass 前默认的勾选取消

可以使用 mongod --version 命令查看 MongoDB 版本,若版本号输出正常则安装完毕

启动数据库(三种方式)

  • cmd + cd到安装路径

    // cmd命令行cd到安装路径
    cd C:\Program Files\MongoDB\Server\3.4\bin
    
    // 然后cmd启动MongoDB,执行cmd命令
    mongod.exe --dbpath E:\db\MongoDB
    
  • 按照如下顺序,添加全局变量

    桌面 > 我的电脑 > 鼠标右键选择 > 属性 > 高级系统属性 > 环境变量 > 全局变量 > 选择编辑 Path,将 MongoDB 的安装目录添加到列表,如 C:\Program Files\MongoDB\Server\3.4\bin
    
    然后,打开 cmd 执行命令: mongod
    
    最后,cmd 执行命令: mongod --dbpath E:\db\MongoDB // 修改数据库位置
    

    默认情况下,通过命令启动的数据库目录在 命令执行所在盘符根目录 /data/db 文件

    服务器和操作服务器是两个进程,可以修改默认数据库路径

    mongod --dbpath '数据库自拟路径'
    
  • 自定义 .bat 批处理文件

    在修改了全局变量 path 的变量路径之后,在本地新建一个文本文档,修改文件后缀名为 .bat(.bat文件命名:不能有空格出现,尽量英文,可使用下划线间隔)
    
    打开该.bat批处理文件,添加如下代码,并保存文件
    echo "MongoDB starting.........."
    mongod --dbpath E:\db\MongoDB
    pause
    
    鼠标双击该批处理文件,正常情况下,就会快速启动 MongoDB 数据库服务
    

关闭数据库

mongod  --shutdown

使用默认端口来连接 MongoDB 服务

mongo

数据库操作

  • 显示所有已存在的数据库

    show dbs
    

    在显示的结果中 adminlocal 两个结果为系统数据库

  • 删除数据库

    db.dropDatabase()
    

    删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名

    以下实例我们删除了数据库 runoob

    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    runoob  0.000GB
    

    接下来我们切换到数据库 runoob

    > use runoob
    switched to db runoob
    

    执行删除命令

    > db.dropDatabase()
    {
            "dropped" : "runoob", "ok" : 1 }
    
  • 切换到目标数据库

    use demo
    

    通过命令 use + 目标数据库名 ,既可切换到目标数据库

  • 查看当前操作数据库

    db
    

    通过 db 命令可以查看当前操作的数据库

    这里需要注意的是,当数据库中没有数据时,数据库不予显示

  • 显示当前数据库的所有集合

    show collections
    

    查看当前 db 数据库中存在的所有集合

    这里需要注意的是,当集合中没有数据时,合集不予显示

以下操作,如果集合中包含特殊字符,如\、/等,(比如:s-tudents)这样在使用 mongo shell 时会报错

处理办法是使用 mongodb 的 getCollection 函数,举例说明

db.getCollection('s-tudents').drop()
  • 删除集合

    db.students.drop()
    
  • 清空集合中的数据

    db.students.remove({
           })
    
  • 显示当前集合中所有数据

    db.students.find()
    

    通过 db. + 当前集合名称 + .find() 可以查看当前集合中的所有数据

  • 向当前集合添加数据

    db.students.insertOne({
           name: 'demo'})
    

    通过 db. + 当前集合名称 + .insertOne({ + 数据对象 + }) 可以向当前集合中添加数据

  • 断开 MongoDB 服务

    exit
    
  • 断开数据库链接

    db.shutdownServer()
    

MongoDB 备份与恢复

  • 备份(mongodump)

    在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中

    mongodump命令脚本语法如下:

    mongodump -h dbhost -d dbname -o dbdirectory
    // -h:MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
    // -d:需要备份的数据库实例,例如:test
    // -o:备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据
    
  • 恢复(mongorestore)

    mongodb使用 mongorestore 命令来恢复备份的数据

    mongorestore命令脚本语法如下:

    mongorestore -h <hostname><:port> -d dbname <path>
    // --host <:port>, -h <:port>:MongoDB所在服务器地址,默认为: localhost:27017
    // --db , -d :需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
    // --drop:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
    // :mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。你不能同时指定  和 --dir 选项,--dir也可以设置备份目录
    // --dir:指定备份的目录,你不能同时指定  和 --dir 选项
    

    接下来我们执行以下命令:

    mongorestore
    

Mongoose

介绍

Mongoose 是在 node.js 异步环境下对 mongodb 进行便捷操作的对象模型工具

安装

npm install mongoose

使用

var mongoose = require('mongoose'); // 引入 mongoose
mongoose.connect('mongodb://localhost/test'); // 通过 mongoose 连接 mongodb 数据库

连接数据库的默认端口为 27017

.connect 中返回一个状态待定(pending)的连接, 可供我们对连接成功与否进行监测

var db = mongoose.connection; // 数据库连接状态
db.on('error', console.error.bind(console, 'connection error:')); // 数据库连接失败
db.once('open', function() {
     
  // we're connected!(数据库连接成功)
});

.on 的第一个参数可选值为 connectederrordisconnected ,分别用于监测 连接成功、链接异常、链接断开

创建模型,设计数据库

var kittySchema = mongoose.Schema({
     
  name: String,
  // 也可以如下写法
  name: {
     
    type: String, // 数据类型
    required: Boolean, // 是否为必须
    defaule: '张三', // 默认值
    enum: ['张三', '李四', '王五', '赵六'] // 枚举,默认值只可是枚举值
  }
}
});
var Kitten = mongoose.model('Kitten', kittySchema);

mongoose.model 用于将一个数据库模型发布为 model

以上代码中,相当于创建了一个名为 Kitten 的集合,该集合内部的数据结构中有一条数据名为 name ,且是 字符串 类型

使用 Kitten 以下代码创造一条数据

var felyne = new Kitten({
      name: 'Felyne' });

此时,集合 Kitten 中会增加一条 nameFelyne 的数据,Felyne 的数据类型为 String

通过 .save 方法可以验证数据是否保存成功

fluffy.save(function (err, fluffy) {
     
    if (err) return console.error(err);
    fluffy.speak();
});

注意 回调函数的第一个参数永远是 error

  • 增加数据

    Model.save([fn])

    var user = new User({
           
      username: 'kongzhi0707',
      password: '123456'
    });
    user.save(function(err, res) {
           
      if (err) {
           
          return console.log(err);
      }  
      console.log(res);
    });
    
  • 删除数据

    1. 从集合中删除所有符合条件的文档:Model.remove(conditions, [callback])

      conditions:Object

      [callback]:Function

      示例:

      var wherestr = {
               'username': 'kongzhi0707'}; // 删除数据的条件
      User.remove(wherestr, function(err, res) {
               
        if (err) {
               
            return console.log(err);
        }  
        console.log(res);
      });
      
    2. 查找匹配符合 id 的文档,将其删除:Model.findByIdAndRemove(id, [options], [callback])

      id:Object|Number|String

      [options]:Object

      ​ sort:如果条件找到多个文档,请设置排序顺序以选择要更新的文档

      ​ select:设置要返回的文档字段

      ​ rawResult:如果为 true ,则返回 MongoDB 驱动程序的原始结果

      ​ strict:覆盖此更新的架构的严格模式选项

      [callback]:Function

      示例:

      User.findByIdAndRemove(id, options, callback) // executes
      User.findByIdAndRemove(id, options)  // return Query
      User.findByIdAndRemove(id, callback) // executes
      User.findByIdAndRemove(id) // returns Query
      User.findByIdAndRemove()           // returns Query
      
    3. 根据记录 :Model.findOneAndRemove(conditions, [options], [callback])

      conditions:Object

      [options]:Object

      ​ sort:如果条件找到多个文档,请设置排序顺序以选择要更新的文档

      ​ maxTimeMS:对查询设置时间限制

      ​ select:设置要返回的文档字段

      ​ rawResult:如果为 true ,则返回 MongoDB 驱动程序的原始结果

      ​ strict:覆盖此更新的架构的严格模式选项

      [callback]:Function

      示例:

      User.findOneAndRemove(conditions, options, callback) // executes
      User.findOneAndRemove(conditions, options)  // return Query
      User.findOneAndRemove(conditions, callback) // executes
      User.findOneAndRemove(conditions) // returns Query
      User.findOneAndRemove()           // returns Query
      
  • 更新数据

    1. 根据条件更新数据库中的一个文档:Model.update(conditions, doc, [options], [callback])

      conditions:Object

      doc:Object

      [options]:Object

      ​ safe:(布尔值)安全模式(默认为在架构(true)中设置的值)

      ​ upsert:(布尔值)是否创建不匹配的文档(假)

      ​ multi:(布尔值)是否应更新多个文档(假)

      ​ runValidators:如果为 true ,则对此命令运行更新验证程序。更新验证器根据模型的架构验证更新操作

      ​ setDefaultsOnInsert:如果 this 和 upsert 为 true ,则在创建新文档时,猫鼬将应用模型模式中指定的默认值(此选项仅在MongoDB >= 2.4上有效)

      ​ strict:(布尔值)会覆盖此更新的严格选项

      ​ overwrite:(布尔值)禁用仅更新模式,从而允许您覆盖文档(false)

      [callback]:Function

      示例:

      var wherestr = {
               'username': 'kongzhi0707'}; // 更新数据的条件查询
      var updatestr = {
               'password': 'abcdef'}; // 执行更新数据
      User.update(wherestr, updatestr, function(err, res) {
               
        if (err) {
               
            return console.log(err);
        }  
        console.log(res);
      });
      
    2. 通过文档的 _id 字段更新数据库中的一个文档 :Model.findByIdAndUpdate(id, [update], [options], [callback])

      id:Object|Number|String

      [update]:Object

      [options]:Object

      ​ new:bool-true,返回修改后的文档而不是原始文档(默认为 false )

      ​ upsert:bool-创建对象(如果不存在)(默认为false)

      ​ runValidators:如果为true,则对此命令运行更新验证程序。更新验证器根据模型的架构验证更新操作

      ​ setDefaultsOnInsert:如果 this 和 upsert 为 true ,则在创建新文档时,猫鼬将应用模型模式中指定的默认值(此选项仅在MongoDB >= 2.4上有效)

      ​ sort:如果条件找到多个文档,请设置排序顺序以选择要更新的文档

      ​ select:设置要返回的文档字段

      ​ rawResult:如果为true,则返回MongoDB驱动程序的原始结果

      ​ strict:覆盖此更新的架构的严格模式选项

      [options.lean]:Object

      [callback]:Function

      示例:

      User.findByIdAndUpdate(id, update, options, callback) // executes
      User.findByIdAndUpdate(id, update, options)  // returns Query
      User.findByIdAndUpdate(id, update, callback) // executes
      User.findByIdAndUpdate(id, update)           // returns Query
      User.findByIdAndUpdate()                     // returns Query
      
    3. 根据记录:Model.findOneAndUpdate([conditions], [update], [options], [callback])

      [conditions]:Object

      [update]:Object

      [options]:Object

      ​ new:bool-如果为true,则返回修改后的文档而不是原始文档(默认为false)

      ​ upsert:bool-创建对象(如果不存在)(默认为false)

      ​ fields:{Object | String} 等效于 .select(fields).findOneAndUpdate()

      ​ maxTimeMS:对查询设置时间限制-需要 mongodb >= 2.6.0

      ​ sort:如果条件找到多个文档,请设置排序顺序以选择要更新的文档

      ​ runValidators:如果为 true ,则对此命令运行更新验证程序。更新验证器根据模型的架构验证更新操作

      ​ setDefaultsOnInsert:如果 this 和 upsert 为 true ,则在创建新文档时,猫鼬将应用模型模式中指定的默认值(此选项仅适用于MongoDB >= 2.4)

      ​ rawResult:如果为true,则返回MongoDB驱动程序的原始结果

      ​ strict:覆盖此更新的架构的严格模式选项

      [options.lean]:Object

      [callback]:Function

      示例:

      User.findOneAndUpdate(conditions, update, options, callback) // executes
      User.findOneAndUpdate(conditions, update, options)  // returns Query
      User.findOneAndUpdate(conditions, update, callback) // executes
      User.findOneAndUpdate(conditions, update)           // returns Query
      User.findOneAndUpdate()                             // returns Query
      
  • 查询数据

    1. 根据条件查找文件:Model.find(conditions, [fields], [options], [callback]);

      conditions:Object

      [projection]:Object

      [options]:Object

      [callback]:Function

      示例:

      var wherestr = {
               'userName': '龙恩0707'}; // 删除数据的条件
      User.find(wherestr, function(err, res) {
               
      if (err) {
               
            return console.log(err);
      }  
        console.log(res);
      });
      
    2. 通过其 _id 字段查找单个文档:Model.findById(id, [projection], [options], [callback])

      id:Object|String|Number

      [projection]:Object

      [options]:Object

      [callback]:Function

      示例:

      Adventure.findById(id, function (err, adventure) {
               }); // find adventure by id and execute immediately
        
      Adventure.findById(id).exec(callback); // same as above
      
      Adventure.findById(id, 'name length', function (err, adventure) {
               }); // select only the adventures name and length
      
      Adventure.findById(id, 'name length').exec(callback); // same as above
      
      Adventure.findById(id, '-length').exec(function (err, adventure) {
               }); // include all properties except for `length`
      
      Adventure.findById(id, 'name', {
                lean: true }, function (err, doc) {
               }); // passing options (in this case return the raw js objects, not mongoose documents by passing `lean`
      
      Adventure.findById(id, 'name').lean().exec(function (err, doc) {
               }); // same as above
      
    3. 根据记录:Model.findOne([conditions], [projection], [options], [callback])

      id:Object|String|Number

      [projection]:Object

      [options]:Object

      [callback]:Function

      示例:

      Adventure.findById(id, function (err, adventure) {
               }); // find adventure by id and execute immediately
      
      Adventure.findById(id).exec(callback); // same as above
      
      Adventure.findById(id, 'name length', function (err, adventure) {
               }); // select only the adventures name and length
      
      Adventure.findById(id, 'name length').exec(callback); // same as above
      
      Adventure.findById(id, '-length').exec(function (err, adventure) {
               }); // include all properties except for `length`
      
      Adventure.findById(id, 'name', {
                lean: true }, function (err, doc) {
               }); // passing options (in this case return the raw js objects, not mongoose documents by passing `lean`
      
      Adventure.findById(id, 'name').lean().exec(function (err, doc) {
               }); // same as above
      
    4. 范围查询:

      User.find({
               userage: {
               gte: 21,lte: 65}}, callback); //这表示查询年龄大于等21而且小于等于65岁
      

      可用的部分类似范围查询条件还有:

      o r ∗ ∗ : 或 关 系 ∗ ∗ or**:或关系 ** ornor:或关系取反 g t ∗ ∗ : 大 于 ∗ ∗ gt**:大于 ** gtgte:大于等于

      l t ∗ ∗ : 小 于 ∗ ∗ lt**: 小于 ** ltlte:小于等于 n e ∗ ∗ : 不 等 于 ∗ ∗ ne**:不等于 ** nein:在多个值范围内

      n i n ∗ ∗ : 不 在 多 个 值 范 围 内 ∗ ∗ nin**:不在多个值范围内 ** ninall:匹配数组中多个值 $regex:正则,用于模糊查询

      s i z e ∗ ∗ : 匹 配 数 组 大 小 ∗ ∗ size**:匹配数组大小 ** sizemaxDistance:范围查询,距离(基于LBS)

      m o d ∗ ∗ : 取 模 运 算 ∗ ∗ mod**:取模运算 ** modnear:邻域查询,查询附近的位置(基于LBS)

      e x i s t s ∗ ∗ : 字 段 是 否 存 在 ∗ ∗ exists**:字段是否存在 ** existselemMatch:匹配内数组内的元素

      w i t h i n ∗ ∗ : 范 围 查 询 ( 基 于 L B S ) ∗ ∗ within**:范围查询(基于LBS) ** withinLBSbox:范围查询,矩形范围(基于LBS)

      c e n t e r ∗ ∗ : 范 围 醒 询 , 圆 形 范 围 ( 基 于 L B S ) ∗ ∗ center**:范围醒询,圆形范围(基于LBS) ** centerLBScenterSphere:范围查询,球形范围(基于LBS)

      $slice:查询字段集合中的元素(比如从第几个之后,第N到第M个元素)


资料参考:

  • [MongoDB 官网]
  • [MongoDB 教程]
  • [Mongoose.js中文网]
  • [数据库MongoDB启动方式(3种) - 方法总结篇]
  • [MongoDB 备份(mongodump)与恢复(mongorestore)]

你可能感兴趣的:(node,mongodb,node.js)