node.js操作數據庫之MongoDB+mongoose篇


前言

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)"

安裝過程會有點長,終端輸出信息超過一屏,這里我只截取了頭尾兩部分。
mg-install-homebrew.jpg

mg-install-homebrew-2.jpg

2. 然后獲取下 MongoDB Homebrew Tap

brew tap mongodb/brew

mg-tap-mongodb-brew.jpg

3. 最后安裝 MongoDB CE(社區版)

brew install mongodb-community@4.2

mg-brew-install-mongodb.jpg

現在你的 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

mg-install-mongoose.jpg

現在,你的開發環境就已經全部安裝好了。

二、啟動MongoDB服務

要操作 MongoDB ,首先要啟動它。
有兩種方式啟動 MongoDB 服務:

1. 在前台運行

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

前台運行的好處就是,可以查看一些反饋和日志,便於調試。另外如果要關閉服務,只需要在終端按 control + c 鍵即可。
mg-run-mongodb-in-foreground.jpg

2. 也可以作為 macOS 服務,在后台運行

brew services start mongodb-community@4.2

好處是開機就自動啟動,隨時可以使用。
mg-run-mongodb-as-a-server.jpg
這種啟動方式,如果要關閉服務,可以通過 stop 命令:

brew services stop mongodb-community@4.2

mg-stop-mongodb-service.jpg

現在,你的 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

mg-connection.jpg

可以看到打印出“打開 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版安裝即可。

mg-robo3T-download2.jpg

點擊 Robo3T 左上角連接我們的數據庫后,可以看到 MongoDB 自動幫我們生成了數據庫和集合,並且已經插入了一條記錄:

mg-insert.jpg

或者還可以直接通過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

mg-guery.jpg

可以看到namelisi的記錄被打印了出來。

如果想查詢整個集合:

// 不放查詢條件即查詢所有的記錄
StudentModel.find({}).then(doc => {
    console.log(doc);
})

mg-guery-all.jpg

可以看到集合中的所有記錄被打印了出來。

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,可以看到數據被更改,切換到表格模式更加直觀:

mg-update2.jpg

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

mg-update.jpg

意思是建議我們使用 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的記錄了:

mg-remove2.jpg

在看終端的輸出,跟update類似,也提示建議使用新的方法代替。

mg-remove.jpg

意思是建議我們使用 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篇 | 掘金


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM