一、Mongodb 介绍
Mongodb 是一个文档数据库,以文档形式存储数据,格式类似于 JSON
与 Mysql 的特点及选型对照
| Mongodb | Mysql | |
|---|---|---|
| 关系类型 | 非关系型 | 关系型 | 
| 存储类型 | 文档存储(类似于写 Word ) | 表格存储 (类似于写 Excle) | 
| 操作类型 | NoSQL 操作 (不需要写 sql 语句) | SQL 操作 | 
| 选型对照 | 适合存储格式比较松散的信息,如"爬虫"下来的数据 | 适合存储格式比较规整的信息 | 
说明 :并不是说在真实项目中,两种数据库只能选其一, 二者是可以同时使用的。对于用户信息表等规整信息可以采用 Mysql 数据库存储,而对于网页中类似博客内容等大段的富文本信息(同时包含文本、视频、图片等),放到 Mysql 数据库中的一个字段中存储就不太合适了。
二、Mongodb 及 Compass 安装
网上安装的资料很多,这里就不在重复了,大家可以根据以下参考博客进行安装
Mongodb 安装
安装后默认的运行了 Mongodb 服务器,以及连接上了 Mongodb, 可以直接通过命令行进行操作了。如果你还连接不上 Mongodb ,请参考上面安装连接中的配置。
Mongodb Compass 安装
Mongodb Compass 是官方推荐的一款可视化工具,可以方便直观的进行数据的浏览和操纵
安装链接
https://link.juejin.cn?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2Fca1e722b6788
三、重要概念
1、和 Mysql 的差异
对于关系型数据库,使用时通常是先创建数据库,再创建表,然后对记录的增删改查
但在 Mongodb 中这些名词上有些差异,操作步骤如下:
- 创建一个数据库 (
database) -- 和Mysql相同 - 创建集合 (
collection) -- 对应Mysql中的表 - 对文档 (
document) 的增删改查 -- 对应Mysql中记录的增删改查 
2、BSON
Mongodb的文档使用的格式是BSONBSON= BinaryJSON,是二进制类型的JSON
四、使用 Compass 操作 Mongodb
1、打开后的界面如图所示,点击 "CONNECT" 进行连接

2、新安装的 Mongodb 默认带了三个数据库; 点击 "CREATE DATABASE" 进行创建数据库

3、创建数据库和集合

4、点击 "ADD DATA" 可以增加文档

5、文档的格式如下图 :

6、对文档的查找、修改和删除

注:查找时输入的数据也是类似于 JSON 的格式
五、使用命令行操作 Mongodb
打开 Mongodb 目录下 bin/mongo.exe
注:dbName、collName 等 请改为自己创建的数据库或集合的名字
1、查看操作
# 查看有哪些数据库
show dbs
# 创建或进入数据库 (当数据库不存在即创建)
use dbName
# 查看有哪些集合
show collections
        2、创建集合 / 向集合中插入文档
# 可以直接向集合插入数据,对不存在的集合将会创建
db.collName.insert({"name":"Axton", "age":20}) 
        3、显示集合中的文档
# 显示集合中全部文档
db.collName.find()
# 显示集合中特定文档
db.collName.find({ "name":"Axton" })
# 排序,按 ID 倒序排序
db.collName.find().sort({_id:-1})
        4、更新文档
db.collName.update({"name":"Axton", $set:{"name": "Axton2"}})
        5、删除文档
db.collName.update({"name":"Axton", $set:{"name": "Axton2"}})
        六、Node.js 中使用 mongodb 插件连接数据库
1、初始化环境
# 初始化 node.js 环境
npm init -y
# 安装 mongodb 模块
npm i mongodb --save
        2、连接到 Mongodb
const MongoClient = require('mongodb').MongoClient
const url = 'mongodb://localhost:27017'		// 默认端口号为 27017 ,如修改过请自行更改
const dbName = 'mydb'		// 需要连接的数据库名字
MongoClient.connect(
  url,
  {
    // 配置 (默认写上就好)
    useUnifiedTopology: true
  },
  (err, client) => {
    if (err) {
      console.error('mongodn connect error', err)
      return
    }
    console.log('mongodb connect success')
    // 切换到数据库
    const db = client.db(dbName)
    // 关闭连接
    client.close()
  }
)
        3、文档(Document)的操作
查询文档
const MongoClient = require('mongodb').MongoClient
const url = 'mongodb://localhost:27017'
const dbName = 'mydb'
MongoClient.connect(
  url, 
  {
    useUnifiedTopology: true
  },
  (err, client) => {
    if (err) {
      console.error('mongodn connect error', err)
      return
    }
    console.log('mongodb connect success')
    const db = client.db(dbName)
    // 使用集合
    const usersCollection = db.collection('students')
    // ------- 文档的操作代码写在此部分,之后将不再包含连接部分代码 -------
    // 查询文档
    usersCollection.find({	// find() 内不写内容则为查询全部文档
        "name" : "Axton"
    }).toArray((err, res) => {
      if (err) {
        console.error(err)
        return
      }
      console.log(res)
      // find() 为异步操作,为了使查询完后在关闭数据,所以放至此位置
      client.close()
    })
    // -------------------------------------------------------------
  }
)
        插入文档
// 插入一条数据, 插入多条可以选择 insertMany()
usersCollection.insertOne({
  name: 'Jack',
  sex: '男',
  age: 21
}, (err, res) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(res)
  client.close()
})
        更新文档
// 更新一条数据, 更新多条可以选择 updateMany()
usersCollection.updateOne(
  {name: 'Jack'},   // 查询条件
  {$set: {info: '女装'}},   // 更新的内容
   (err, res) => {
     if (err) {
       console.error(err)
       return
     }
     console.log(res)
     client.close()
  }
)
        删除文档
// 删除一条数据, 删除多条可以选择 deleteMany()
usersCollection.deleteOne({
    name: 'Jack'
}, (err, res) => {
    if (err) {
        console.error(err)
        return
    }
    console.log(res)
    client.close()
})
        4、说明
mongodb 是偏底层一点的插件,此处学习使用此插件是为了让大家了解连接 mongodb 的一些原理。在日常中,为了利于项目开发,通常使用 mongoose 插件
七、Node.js 中使用 mongoose 插件连接数据库
1、说明
由于 mongodb 的数据格式过于灵活,容易导致多人开发时数据格式出错,使用 mongoose 可以更加规范的使用数据.
重要名词和操作
- Schema 定义数据格式的规范
 - 以 Model 规范 Collection
 - 规范数据操作的 API
 
2、初始化环境
安装 mongoose 插件
npm i mongoose --save
        目录结构
mongoose-test
├── package-lock.json
├── package.json
├── node_modules
└── src
    ├── db.js
    ├── models
    │	  └── Student.js
    └── test
   	  └── student.js
        3、创建连接服务
db.js
const mongoose = require('mongoose')
const url = 'mongodb://localhost:27017'
const dbName = 'myblog'
mongoose.connect(`${url}/${dbName}`, {
  useUnifiedTopology: true,
  useNewUrlParser: true
})
const db = mongoose.connection    // 将连接对象赋给 db
// 发送错误
db.on('error', err => {
  console.error(err)
})
// 连接成功
db.on('open', () => {
  console.log('success!')
})
module.exports = mongoose
        4、定义 Schema 规范和创建模型
models/Students.js
// 对应 students 集合
const mongoose = require('../db')
// 用 Schema 定义数据规范
const StudentSchema = mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true
  },
  sex: String,
  age: Number
}, {
  timestamps: true  // 时间戳, 在插入、更新数据后将会加上相应的时间数据
  // 在每一条文档中加入 createdAt 和 updatedAt
})
// Model 对于 Collection
const Student = mongoose.model('student', StudentSchema)
module.exports = Student
        5、文档(Document)的操作
test/students.js
查询文档
const Student = require('../models/Student')
// 自执行的异步函数
!(async () => {
    
  // 查询文档
  const res = await Student.find({
    name: 'Axton'
  })
  // 用正则表达式模糊查询文档
  const res2 = await Student.find({
    name: /A/
  })
  
  // 根据 ID 查询单条文档
  const res3 = await Student.findById('5fb2247e6469170600f02551')
})()
        插入文档
const Student = require('../models/Student')
!(async () => {
    
  // 插入文档
  const res = await Student.create({
    name: 'Jack',
    age: 21,
    sex: '男'
  })
})()
        更新文档
const Student = require('../models/Student')
!(async () => {
  // 更新文档
  const res = await Student.findOneAndUpdate(
    {name: 'Jack'},   // 查询的条件
    {sex: '女'},
    {
      new: true  // 返回修改之后的内容,默认为 fasle
    }
  )
})()
        删除文档
const Student = require('../models/Student')
!(async () => {
  // 删除文档
  const res = await Student.findOneAndDelete({
    name: 'Jack'
  })
})()
        八、总结
本文只是把 mongodb 和 node.js 连接 mongodb 等基础操作进行了整理,能用在常用的一些场景中。对于更高级的一些操作可以自行参考官方文档。如果发现本文有错误的地方或者写的不好的地方请在评论区指出。