我年轻时注意到,我每做十件事有九件不成功,于是我就十倍地去努力干下去。——萧伯纳

前言

在大数据的驱使下,我们要实现数据持久化存储,数据共享,数据集中管理数据库是不二之选,小编在这里要阐述的是 mongodb 数据库,mongodb[1]是一个基于分布式文件存储的开源数据库系统,将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组,操作起来比较简单和容易。

1. mongodb

1.1 安装

  • mac 安装地址https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/
brew tap mongodb/brew
brew install mongodb-community@4.2

brew tap mongodb/brew
brew install mongodb-community@4.2
  • windows 安装地址链接:https://pan.baidu.com/s/1O4CeUhR8Gafm4AwJgxS2Qg 提取码:00sk

如果是在 windows 环境下安装,小编这里安装在了 C 盘,那么 C:\MongoDB\bin 下mongod这个是 mongodb 的服务端,mongo是 mongodb 的客户端

1.2 运行

  • mac
$ mongo

$ mongo
  • windows
  • 服务端 C:\MongoDB\bin mongod --dbpath=./data(这里的 data 是新建需要新建 data 文件夹,在文件夹里创建 db 文件夹)
  • 客户端 C:\MongoDB\bin mongo

注意: 如果出现在 windows 下出现小黑窗口闪退的情况,我们需要创建 data 文件夹,然后再 data 文件夹里创建 db 文件,之后再去执行启动服务端的命令,因为 mongodb 默认读取 D 盘的文件下的 data 如果没有就会出现闪退的情况。



mongodb 程序使用外网连接地址连接不上 连接工具可以 mongodb连接失败怎么办_数据库

1.3 数据库的基本操作

  • 显示表
show dbs;

show dbs;
  • 切换数据库
use test;

use test;
  • 插入数据
db.test.insert({name:"vivo"});

 db.test.insert({name:"vivo"});
  • 查询数据
db.test.find();

db.test.find();

更多的命令行操作请参考https://www.runoob.com/mongodb/mongodb-create-database.html[2]


在我们的 node 开发中,MongoDB 是支持 JavaScript 语言的,mongoose[3]就是 node.js 异步环境提供连接 mongodb 的一个库。

2. mongoose

2.1 安装

npm i mongoose -S

npm i mongoose -S

2.2 使用

在 node.js 里采用的是CommonJS[4]的规范,需要我们采用 require 的方法来引入需要的包。

// use mongoose
const mongoose = require("mongoose");

// use mongoose
const mongoose = require("mongoose");

2.3 创建连接

//引入mongoose模块
let mongoose = require("mongoose");
//创建对数据库的连接
let connect = mongoose.createConnection(
    'mongodb://127.0.0.1:27017/cms',
    {
        useNewUrlParser: true,//使用新的url解析
        useUnifiedTopology: true  //新的服务器发现和监视引擎
    }
)
connect.on("open",()=>{
    console.log('当mongodb成功连接数据库之后会打印这个日志');
})
connect.on("error",(error)=>{
    console.log('如果连接失败了,会把失败的原因传递给',error);
})

module.exports = connect

//引入mongoose模块
let mongoose = require("mongoose");
//创建对数据库的连接
let connect = mongoose.createConnection(
    'mongodb://127.0.0.1:27017/cms',
    {
        useNewUrlParser: true,//使用新的url解析
        useUnifiedTopology: true  //新的服务器发现和监视引擎
    }
)
connect.on("open",()=>{
    console.log('当mongodb成功连接数据库之后会打印这个日志');
})
connect.on("error",(error)=>{
    console.log('如果连接失败了,会把失败的原因传递给',error);
})

module.exports = connect

如果不加{ useNewUrlParser: true, useUnifiedTopology: true }这几句话的话,控制台会报出警告的提示,像我这种有警告强迫症的人来说,还是加上吧 ?。

2.4 Schema

定义 Schema 来说其实是用来定义文档的基本字段和集合,也可以理解为表结构的定义。Schema 是与数据无关的 并不能直接操作数据库。

const Schema = mongoose.Schema;
let UserSchema = new Schema({
    name:String,
    age:Number
},{collection:'user'})

const Schema = mongoose.Schema;
let UserSchema = new Schema({
    name:String,
    age:Number
},{collection:'user'})

在 mongoose 中,提供了 Schema 的类,我们可以在实例化的时候先定义mongoose.Schema,以免后续总是要出现丑陋的new mongoose.Schema()

支持的基本类型

  • String
  • Number
  • Date
  • Buffer
  • Boolean
  • Mixed
  • ObjectId
  • Array

其中MixedObjectId是 mongoose 特有的。

官网给的解释是:

Mixed是一种无模式类型,"anything"随便什么都可以,一般使用Schema.Types.Mixed或者{}来表示。

ObjectId是一种特殊类型,用于唯一标识符,可以理解为主键,一般使用mongoose.Types.ObjectId

更多的文档参考https://mongoosejs.com/docs/schematypes.html[5]

?有人可能会问为什么 ObjectId 可以做唯一标识符呢,不会重复吗?

2.5 ObjectId

一个 ObjectId 其实可以分割为四部分,即当前时间戳当前主机的hash当前进程id自动增加的计数器,有了这几个基本上就可以保证它的唯一性了。

  • 当前时间戳
let id = '5f2221af6fd5e827dc5619b6';
let ts='5f2221af';
console.log(parseInt(ts,'10'));
console.log(new Date(parseInt(ts,'16')*1000));

let id = '5f2221af6fd5e827dc5619b6';
let ts='5f2221af';
console.log(parseInt(ts,'10'));
console.log(new Date(parseInt(ts,'16')*1000));



mongodb 程序使用外网连接地址连接不上 连接工具可以 mongodb连接失败怎么办_mongodb_02

?不懂 parseInt()里面第二个参数的[6]

  • 当前主机 hash
let host = '6fd5e8';

let host = '6fd5e8';
  • 当前进程 id
let pid = '27dc';
console.log(parseInt(pid,'16'));  //10204  十进制数  表示 当前进程id

let pid = '27dc';
console.log(parseInt(pid,'16'));  //10204  十进制数  表示 当前进程id



mongodb 程序使用外网连接地址连接不上 连接工具可以 mongodb连接失败怎么办_数据库_03

  • 自动增加计数器
let seq = '5619b6';  //自动增加的计数器

let seq = '5619b6';  //自动增加的计数器

2.6 Model

Model 模型是操作数据库最直接的部分,它代表整个集合 ,操作对象是整个集合。怎么定义 Model 呢?

let UserModel = connection.model('User',UserSchema);
let UserModel2 = connection.model("User");
console.log(UserModel == UserModel2);

let UserModel = connection.model('User',UserSchema);
let UserModel2 = connection.model("User");
console.log(UserModel == UserModel2);



mongodb 程序使用外网连接地址连接不上 连接工具可以 mongodb连接失败怎么办_mongodb_04

  • 传两个参数表示定义模型
  • 传一个参数表示引用或者说是获取这个模型
UserModel.create({name:'vivo'},(err,doc)=>{
     //err是错误对象
     //doc是保存成功之后的文档对象
    console.log(err);
    console.log(doc);
})

UserModel.create({name:'vivo'}).then(result=>{
    console.log(result);
})

UserModel.create({name:'vivo'},(err,doc)=>{
     //err是错误对象
     //doc是保存成功之后的文档对象
    console.log(err);
    console.log(doc);
})

UserModel.create({name:'vivo'}).then(result=>{
    console.log(result);
})

上述两种写法都可以,第一种写法是遵循 node 的开发习惯,callback中的第一个参数永远是错误信息,第二个参数是正确信息。第二种写法是返回promise

上述定义 model 的方法是通过 model 类创建的,还有一种创建 model 的方法是通过实例创建,这个创建出来的是一个操作对象,代表是一个单个文档只能操作自己。

let user1 = new UserModel({
    name:"vivo"
})
user1.save().then(doc=>{
    console.log(doc);
})

let user1 = new UserModel({
    name:"vivo"
})
user1.save().then(doc=>{
    console.log(doc);
})

最后

本文结束,有什么问题和有错误的地方,欢迎大家的留言和评论,还有后续更新,下期更加精彩 ???

参考资料


[1]

菜鸟教程: https://www.runoob.com/mongodb/mongodb-intro.html


[2]

mongodb命令行: https://www.runoob.com/mongodb/mongodb-create-database.html


[3]

mongoose官网: https://mongoosejs.com


[4]

CommonJS规范: https://javascript.ruanyifeng.com/nodejs/module.html


[5]

mongoose官网: https://mongoosejs.com/docs/schematypes.html


[6]

parseInt: https://www.w3school.com.cn/jsref/jsref_parseInt.asp