前言

node.js的出现,使得用前端语法(javascript)开发后台服务成为可能,越来越多的前端因此因此接触后端,甚至转向全栈发展。后端开发少不了数据库的操作。MongoDB是一个基于分布式文件存储的开源数据库系统。本文为大家详细介绍了如何用node.js + mongoose 玩转MongoDB。希望能帮到有需要的人。

由于我用Mac开发,以下所有操作都是在Mac下进行。

一、 环境搭建

安装Node.js

有 node 环境的可以跳过。

nodejs官网提供了 macOS 安装包,直接下载安装即可。现在 nodejs 稳定版已经到了12.11.1

安装MongoDB

MongoDB 是为现代应用程序开发人员和云时代构建的基于文档的通用分布式数据库。

上个月(9月) macOS 包管理器 Homebrew 宣布移除 MongoDB 。原因是去年10月 MongoDB 宣布将其开源许可证从 GNU AGPLv3 切换到 SSPL(Server Side Public License),以此回应 AWS 等云厂商将 MongoDB 以服务的形式提供给用户而没有回馈社区的行为,MongoDB 希望从软件即服务上获取收入。Homebrew 认为 MongoDB 已经不再属于开源范畴...

言归正传,由于上述原因,我们不能直接使用brew install mongodb来安装 MongoDB 了。好在 MongoDB 自己维护了一个定制化的 Homebrew tap。并在 Install MongoDB Community Edition 更新了安装步骤。

Mac下 MongoDB 的最新安装步骤如下:

1. 首先安装 Homebrew

Homebrew 是 macOS 的包管理器。因为 OSX 默认不包含 Homebrew brew 包,所以要先安装,已经安装过的可以跳过。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装过程会有点长,终端输出信息超过一屏,这里我只截取了头尾两部分。

2. 然后获取下 MongoDB Homebrew Tap

brew tap mongodb/brew

3. 最后安装 MongoDB CE(社区版)

brew install mongodb-community@4.2

现在你的 Mac 上就已经安装好 MongoDB 环境了。

安装mongoose

node.js 是可以直接操作 MongoDB 的,但是通过 MongoDB 命令语法直接编写 MongoDB 验证、数据类型转换和业务逻辑模版比较繁琐。所以我们使用了 mongoose。

mongoose 是 MongoDB 的一个对象模型工具,它对 MongoDB 的常用方法进行了封装,让 node.js 操作 MongoDB 更加优雅简洁。

刚才的 node.js 和 MongoDB 都是安装在全局环境,mongoose 则是安装在你的项目下:

cd your-project
npm i -S mongoose

现在,你的开发环境就已经全部安装好了。

二、启动MongoDB服务

要操作 MongoDB ,首先要启动它。

有两种方式启动 MongoDB 服务:

1. 在前台运行

mongod --config /usr/local/etc/mongod.conf

前台运行的好处就是,可以查看一些反馈和日志,便于调试。另外如果要关闭服务,只需要在终端按 control + c 键即可。

2. 也可以作为 macOS 服务,在后台运行

brew services start mongodb-community@4.2

好处是开机就自动启动,随时可以使用。



这种启动方式,如果要关闭服务,可以通过 stop 命令:

brew services stop mongodb-community@4.2

现在,你的 MongoDB 数据库已经开启了。

三、操作MongoDB

操作之前先解释一下MongoDB和mongoose里的一些核心概念。

MongoDB

  • MongoDB 中的数据记录是一种 BSON 格式的文件(BSON是一种用二进制描述的JSON文件格式)。
  • MongoDB 将文件存储在集合中,将集合存储在数据库中。
  • MongoDB 的数据库、集合都不用手动创建。
  • 集合collection: 相当于关系型数据库中的表table
  • 文件document: MongoDB 的数据记录单位,相当于关系型数据库中的记录row

mongoose

  • schema: 在 mongoose 中,所有的东西都来源于一个 schema,每个schema 映射了一个 MongoDB 的集合,它定义了这个集合中的文档的骨架。
  • model: 一个文件的构造器,通过编译schema得到,一个model的实例就是一个文件model负责从 MongoDB 数据库中创建和读取文档

更多mongoose概念可以在mongoose guide中查阅。

数据库操作:

1. 使用 mongoose 连接 MongoDB

在项目中创建 connection.js 文件

// connection.js file
const mongoose = require('mongoose');
const conn = mongoose.createConnection( // 连接地址,MongoDB 的服务端口为27017
// dbtest是我要使用的数据库名,当往其中写数据时,MongoDB 会自动创建一个名为dbtest的数据库,不用事先手动创建。
'mongodb://127.0.0.1:27017/dbtest', // 一些兼容配置,必须加,你不写运行的时候会提示你加。
{
useNewUrlParser: true,
useUnifiedTopology: true
}
)
conn.on('open', () => {
console.log('打开 mongodb 连接');
})
conn.on('err', (err) => {
console.log('err:' + err);
})

运行:

node conection.js

可以看到打印出“打开 mongodb 连接”,并且运行一直在等待。

这说明现在已经成功连接上 MongoDB 了,接下来可以开始操作数据库了。

为了方便扩展起见,我们先对 connection.js 改造一下,让它作为模块导出,这样就可以在其他地方导入复用了。

// connection.js file
const mongoose = require('mongoose');
const conn = mongoose.createConnection(
'mongodb://127.0.0.1:27017/dbtest',
{
useNewUrlParser: true,
useUnifiedTopology: true
}
)
conn.on('open', () => {
console.log('打开 mongodb 连接');
})
conn.on('err', (err) => {
console.log('err:' + err);
}) module.exports = conn; //commonJs 语法,导出conn模块。

2. 添加操作

save | create 方法

新建insert.js文件

// insert.js file
let mongoose = require('mongoose'); // 导入连接模块
let connection = require('./connection'); // 创建schema
let StudentSchema = new mongoose.Schema({
name: String,
age: Number
}) // 通过connection和schema创建model
let StudentModel = connection.model('Student', StudentSchema); // 通过实例化model创建文档
let studentDoc = new StudentModel({
name: 'zhangsan',
age: 20
}) // 将文档插入到数据库,save方法返回一个Promise对象。
studentDoc.save().then((doc) => {
console.log(doc)
})

运行:

node insert.js

为了更直观看到操作数据库的结果,推荐大家安装一个数据库可视化工具:Robo3T,下载mac版安装即可。

点击 Robo3T 左上角连接我们的数据库后,可以看到 MongoDB 自动帮我们生成了数据库和集合,并且已经插入了一条记录:

或者还可以直接通过Model的create方法直接插入数据,返回的也是一个Promise:

StudentModel.create({
name: 'lisi',
age: 19
}).then((doc) => {
console.log(doc)
})

3. 读取操作

find 方法

为更加合理复用代码,我们先把 StudentSchema 和 StudentModel 抽离出来:

新建StudentSchema.js翁建

// StudentSchema.js file
const mongoose = require('mongoose'); let StudentSchema = mongoose.Schema({
name: String,
age: Number
}) module.exports = StudentSchema;

新建StudentModel.js文件

// StudentModel.js file
const connection = require('./connection');
const StudentSchema = require('./StudentSchema'); let StudentModel = connection.model('Student', StudentSchema); module.exports = StudentModel;

然后新建query.js文件

// query.js file
const StudentModel = require('./StudentModel'); // 富查询条件,对象格式,键值对,下面为查询 name 为 lisi 的记录
StudentModel.find({name: 'lisi'}).then(doc => {
console.log(doc);
})

运行

node query.js

可以看到namelisi的记录被打印了出来。

如果想查询整个集合:

// 不放查询条件即查询所有的记录
StudentModel.find({}).then(doc => {
console.log(doc);
})

可以看到集合中的所有记录被打印了出来。

4. 更新操作

update|updateOne|updateMany 方法

新建update.js文件

// update.js file
const StudentModel = require('./StudentModel'); // update 方法接收2个参数,第一个是查询条件,第二个是修改的值
// 下面把name为lisi的记录,将他的age修改为80
StudentModel.update({name: 'lisi'}, {age: 80}).then(result => {
console.log(result)
})

进入 Robo3T,可以看到数据被更改,切换到表格模式更加直观:

不过在终端,提示DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.

意思是建议我们使用 updateOneupdateMany或者bulkWrite

  • update 更新查询到的所有结果,方法已经不提倡使用,已被updateMany替代。
  • updateOne 如果查询到多条结果,只更新第一条记录。
  • upateMany 更新查询到的所有结果。
  • bulkWrite 提供可控执行顺序的批量写操作。

为了代码的健壮性,我们应该根据建议将update方法换成updateMany方法。

另外,终端的输出{ n: 1, nModified: 1, ok: 1 }的意思是:

  • “n: 1”:查询到1条记录。
  • “nModified: 1”:需要修改1条记录。(如果修改值和原始值相同,则需要修改的就是0条)
  • “ok: 1”:修改成功1条。

5. 删除操作

remove|removeOne|removeMany|bulkWrite 方法

新建remote.js文件

// remove.js file
const StudentModel = require('./StudentModel'); // delete 方法接收1个参数,就是查询条件
// 下面把name为lisi的记录删除
StudentModel.remove({name:'lisi'}).then((result) => {
console.log(result);
});

进入 Robo3T,可以看到集合里已经没有name为lisi的记录了:

在看终端的输出,跟update类似,也提示建议使用新的方法代替。

意思是建议我们使用 removeOneremoveMany或者bulkWrite

  • remove 删除查询到所有结果,方法已经不提倡使用,已被removeMany替代。
  • removeOne 如果查询到多条结果,只删除第一条记录。
  • removeMany 删除查询到所有结果。
  • bulkWrite 提供可控执行顺序的批量写操作。

另外,终端的输出{ n: 1, ok: 1, deletedCount: 1 }的意思跟update的类似,就不累述了。

现在我们已经成功地对 MongoDB 数据库进行了 CRUD(添加、读取、更新、删除)操作。欢呼~

更多高级操作,可以到mongoose API 文档中查阅。

四、总结

梳理一下,主要讲了这些内容:

  1. node.js+MongoDB+mongoose 在Mac下的环境搭建,注意使用最新的 MongoDB 的安装方式。
  2. 在Mac下如何启动和关闭 MongoDB 服务。
  3. 介绍了 MongoDBmongoose 的基本核心概念。
  4. 使用 mongoose 连接以及增删改查 MongoDB 操作。可以使用 Robo3T 来更直观地观察数据库。

前端也能玩转数据库开发。

欢迎交流~

文章源码地址:https://github.com/yc111/mongodb-demo

相关网站:

Homebrew官网

MongoDB官网

monggose官网

Robo3T官网

macOS 包管理器 Homebrew 移除 MongoDB

--

欢迎转载,转载请注明出处:

https://champyin.com/2019/10/10/node.js操作数据库之MongoDB+mongoose篇/

本文同步发表于:

node.js操作数据库之MongoDB+mongoose篇 | 掘金

node.js操作数据库之MongoDB+mongoose篇的更多相关文章

  1. 使用navicat for mysql图形界面操作数据库、使用node.js操作数据库写接口

    1.先启动MYSQL服务 2.打开navicat for mysql, 点击链接,输入如下的内容: 3.新建数据表 4.数据库(新建一个db.js) //数据库链接配置 module.exports ...

  2. node.js操作数据库

    var sys = require('sys'); var Client = require('mysql').Client; var client = new Client(); client.us ...

  3. node.js零基础详细教程(7):node.js操作mongodb,及操作方法的封装

    第七章 建议学习时间4小时  课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...

  4. Node.js 操作Mongodb

    Node.js 操作Mongodb1.简介官网英文文档  https://docs.mongodb.com/manual/  这里几乎什么都有了MongoDB is open-source docum ...

  5. 使用node js 操作 Mysql 数据库

    使用node js 操作 Mysql 数据库 http://www.nodejs.org/ //node js 数据库操作 MySQL //使用https://github.com/felixge/n ...

  6. node.js操作MySQL数据库

    MySQL数据库作为最流行的开源数据库.基本上是每个web开发者必须要掌握的数据库程序之一了. 基本使用 node.js上,最受欢迎的mysql包就是mysql模块. npm install mysq ...

  7. Node.js、express、mongodb 实现分页查询、条件搜索

    前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...

  8. [Node.js与数据库]node-mysql 模块介绍

    [Node.js与数据库]node-mysql 模块介绍   转载至:https://itbilu.com/nodejs/npm/NyPG8LhlW.html#multiple-statement-q ...

  9. [Node.js]操作mysql

    摘要 上篇文章介绍了node.js操作redis的简单实例,这里介绍如何操作mysql. 安装 安装mysql模块 cnpm install mysql 一个例子 新建一个mysql.js的文件,代码 ...

随机推荐

  1. 【DataBase】事务

    一.事务概述 二.事务的四大特性(ACID) 三.事务的隔离性导致的问题 四.数据库的四个隔离级别 五.数据库中的锁机制: 六.更新丢失 七.并发事务所带来的的问题 一.事务概述 事务的概念:事务是指 ...

  2. 运行sudo apt-get install nginx时报错有几个软件包无法下载,要不运行 apt-get update 或者加上 --fix-missing 的选项再试试?解决

    运行sudo apt-get install nginx时报错有几个软件包无法下载,要不运行 apt-get update 或者加上 --fix-missing 的选项再试试?解决办法 第一步:运行s ...

  3. 剑指offer(五):用两个栈实现一个队列

    题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解决办法: 队列先进先出,栈先进后出(stack1和stack2) 其实主要要注意的点是: ①在添加时直接 ...

  4. vmware vsphere client 创建虚拟机

    浏览器访问https://192.168.120.29 用户名:administrator@zhcs.com 密码:  Deyi123456! 说明:此案例为创建linux的Centos7的操作系统的 ...

  5. FreeSql (八)插入数据时指定列

    插入数据时指定列,和忽略列对应,未被指定的列将被忽略. var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Passwor ...

  6. Kafka源码分析及图解原理之Broker端

    一.前言 https://www.cnblogs.com/GrimMjx/p/11354987.html 上一节说过,任何消息队列都是万变不离其宗都是3部分,消息生产者(Producer).消息消费者 ...

  7. STL容器(Stack, Queue, List, Vector, Deque, Priority_Queue, Map, Pair, Set, Multiset, Multimap)

    一.Stack(栈) 这个没啥好说的,就是后进先出的一个容器. 基本操作有: stack<int>q; q.push(); //入栈 q.pop(); //出栈 q.top(); //返回 ...

  8. redis的几个知识点

    Redis的全称是Remote Dictionary Server,即远程字典服务,通常用作服务器缓存服务. 这里通过Redis的几个知识点来了解Redis. Redis的通讯协议 Redis的通讯协 ...

  9. Linux 笔记 - 第十八章 Linux 集群之(二)LVS 负载均衡集群

    一.前言 Linux 集群从功能上可以分为两大类:高可用集群和负载均衡集群.上一篇已经讲解了 HA 高可用集群,此节讲解负载均衡集群. 负载均衡集群(Load Balance Cluseter,简称 ...

  10. Day 16 软件管理

    1.RPM基本概述 1.什么是rpm? RPM全称 RPM Package Manager 缩写,由红帽开发用于软件包的安装升级卸载与查询 2.如何获取rpm包 在我们刚开始学习rpm包,建议先使用本 ...