前言
終於~將進度慢慢的追上之前所學的東西了,對我來說是很好的複習,老是在處理sequelize,偶爾也要複習一下mongodb~!言歸正傳,這篇文章將會對mongoose做個簡單的介紹,並說明如何利用mongoose與本地端的mongodb資料庫做連線。
Before we get started
你需要在電腦安裝以下軟體幫助你實際操作
- mongodb( https://www.mongodb.com )
- mongodb compass( https://www.mongodb.com/products/compass )此為圖形化的資料庫操作工具,可不安裝
mongodb VS mongoose
首先我們必須知道的就是,這兩個東西到底有什麼不同,又有著什麼樣的關係,其實不用想得太複雜,目前你只需要知道
- Mongodb是一種noSQL類型的資料庫。
- mongoose是node.js用來操作 Mongodb 的一種ODM。
很好,又多了個從沒見過的名詞,問題越來越多了。
別擔心,關於ODM/ORM你可以參考這篇文章,其實就是一些名詞的代換而已,程式語言的其中一個特性就是用許多複雜的形容詞把很簡單的東西包裝起來😛
連線設置
首先我們需要建立一個專案資料夾,這邊簡單複習一下操作的指令。
npm init -y //安裝 mongoose套件 npm i mongoose
老樣子,我們在專案資料夾下建立app.js檔案,等等的一切程式都會寫在這支js檔案內
const mongoose = require('mongoose') //建立與mongodb的連線 mongoose.connect('mongodb://localhost/kitten', { useNewUrlParser: true }); //建立db變數讓我們可以設置事件 const db = mongoose.connection //建立連線 db.once('open', () => { console.log('mongodb has been connected'); }) db.on('error', () => { console.log('something went wrong in the connection'); })
上方的程式碼中我們首先建立了與mongodb的連線,連線時需要用到mongoose.connect語法
其中包含了連線的位置(預設的port為27017 你可以特別設置)與選項,上方的例子為最基本的連線需求設置,表示我們將連線到本地端 port號27017的kitten資料庫,若沒有該資料庫會自動新建。
下方我們則根據連線情況搭載事件,一旦連線成功,我們便在終端機印出對應的訊息。
此時你可以簡單試跑一下,順利的話應該會在終端機看到mongodb has been connected的訊息。

建立Schema與 model
在繼續往下之前,首先要先理解資料庫中的階級關係,未來當你不斷的使用mongodb做為你的資料庫時,你的mongodb compass可能會長得像這樣。

如圖片中所示,你可能會有許多不同的資料庫(db),每個資料庫中有許多不同的集合(collections 藍筆的位置),而每個collection中又會有許多不同的文件(documents 紅筆的位置)。
以上圖的例子來說,今天我建立一個shortenUrl的資料庫來做短網址產生器的專案,我需要一個集合去存放我所有的網址紀錄,裡面的每一筆紀錄就是一個文件,未來我就是透過這些集合或是文件去做資料庫的操作。
了解基本概念後,接著我們就必須先建立schema,定義你文件中的架構會是什麼樣子(有什麼屬性)。
// app.js ..skip //建立Schema var kittySchema = mongoose.Schema({ name: String });
我們利用mongoose.Schema建立一個kittySchema ,其中包含著一項name屬性。
接著我們必須將schema轉譯為model, schema 決定了文件的架構,而 model 則負責後續的資料庫操作,每一次的操作我們都是對model下手。
//將建立Schema輸出為model var Kitten = mongoose.model('Kitten', kittySchema);
我們利用mongoose.Schema建立一個名為Kitten的model,其中它的結構來自我們剛剛建立的kittySchema,特別注意一下這個轉譯的舉動會在你的資料庫建立一個kittens的集合。

這邊你可能會覺得有些奇怪,為什麼會有這樣的集合出現?
原因在於mongoose的設計中,若你沒有特別指定,集合的名稱就會是model名稱的複數小寫型態,也因此Kitten model會產生kittens集合、Category model 會產生categories集合,若你不喜歡這樣,可以在轉譯model時自己套入第三個變數做為集合名稱。
var Kitten = mongoose.model('Kitten', kittySchema,'你所希望的集合名稱');
建立model實體(entity)/文件(document)
實體,就像是JS中物件建立實例(instance)一樣,接著我們就要在剛剛建立的集合中插入新的文件囉,mongoose官方文件中提供了三種不同建立實體的方式。
var Tank = mongoose.model('Tank', yourSchema); var small = new Tank({ size: 'small' }); small.save(function (err) { if (err) return handleError(err); // saved! }); // or Tank.create({ size: 'small' }, function (err, small) { if (err) return handleError(err); // saved! }); // or, for inserting large batches of documents Tank.insertMany([{ size: 'small' }], function (err) { });
我們這邊採用第二種作法,.create做示範!
//建立model的實體(entity) Kitten.create({ name: 'Danny' }) .then(cat => console.log(`you create a cat name ${cat.name}`))
mongoose採用了promise-like的寫法,你可以在這邊用then或catch來做資料的處理,運行程式之後你應該會在終端機看見you create a cat name Danny的訊息,打開你的compass確認一下是否有對應的文件產生。

完整程式碼
const mongoose = require('mongoose') //建立與mongodb的連線 mongoose.connect('mongodb://localhost/kitten', { useNewUrlParser: true }); //建立db變數讓我們可以設置事件 const db = mongoose.connection //建立連線 db.once('open', () => { console.log('mongodb has been connected'); }) db.on('error', () => { console.log('something went wrong in the connection'); }) //建立Schema var kittySchema = mongoose.Schema({ name: String }); //將建立Schema輸出為model var Kitten = mongoose.model('Kitten', kittySchema); //建立model的實體(entity) Kitten.create({ name: 'Danny' }).then(cat => console.log(`you create a cat name${cat.name}`))
結語
本篇文章中我們介紹了mongoose的基本概念與應用,下一篇文章我們會介紹如何利用mongoose進行資料查詢,都弄完之後應該就可以做一個簡單的短網址產生器的文章介紹了!