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

  • 关系型数据库
  • 最典型的数据结构是表
  • 关系型数据库是由二维表及其之间的联系所组成的一个数据组织
  • 都需要使用 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:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
// <path>:mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。你不能同时指定 <path> 和 --dir 选项,--dir也可以设置备份目录
// --dir:指定备份的目录,你不能同时指定 <path> 和 --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);
});
  1. 查找匹配符合 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
  1. 根据记录 :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);
});
  1. 通过文档的 _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
  1. 根据记录: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);
});
  1. 通过其 _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
  1. 根据记录: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
  1. 范围查询:
User.find({userage: {gte: 21,lte: 65}}, callback); //这表示查询年龄大于等21而且小于等于65岁

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

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_Usernor:或关系取反 mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_数据_02gte:大于等于

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_数据库_03lte:小于等于 mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_User_04in:在多个值范围内

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_User_05all:匹配数组中多个值 $regex:正则,用于模糊查询

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_数据库_06maxDistance:范围查询,距离(基于LBS)

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_node.js_07near:邻域查询,查询附近的位置(基于LBS)

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_数据_08elemMatch:匹配内数组内的元素

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_数据库_09box:范围查询,矩形范围(基于LBS)

mongodb community 和 Enterprise Server区别 mongodb和mongoose的区别_mongodb_10centerSphere:范围查询,球形范围(基于LBS)

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


资料参考:

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