1. 程式人生 > >node.js操作資料庫之MongoDB+mongoose篇

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

安裝過程會有點長,終端輸出資訊超過一屏,這裡我只截取了頭尾兩部分。

2. 然後獲取下 MongoDB Homebrew Tap

brew tap mongodb/brew

3. 最後安裝 MongoDB CE(社群版)

brew install [email protected]

現在你的 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 [email protected]

好處是開機就自動啟動,隨時可以使用。

這種啟動方式,如果要關閉服務,可以通過 stop 命令:
brew services stop [email protected]

現在,你的 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%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B9%8BMongoDB+mongoose%E7%AF%87/

本文同步發表於:
node.js操作資料庫之MongoDB+mongoose篇 | 掘