連線 (Connections)
您可以使用 mongoose.connect()
方法連線至 MongoDB。
mongoose.connect('mongodb://127.0.0.1:27017/myapp');
這是連線至在本機預設埠 (27017) 上執行的 myapp
資料庫所需的最基本條件。對於本機 MongoDB 資料庫,我們建議使用 127.0.0.1
而不是 localhost
。這是因為 Node.js 18 及更新版本偏好 IPv6 位址,這表示在許多機器上,Node.js 會將 localhost
解析為 IPv6 位址 ::1
,而 Mongoose 將無法連線,除非 mongodb 執行個體啟用 IPv6。
您也可以在 uri
中指定更多參數
mongoose.connect('mongodb://username:password@host:port/database?options...');
如需更多詳細資訊,請參閱 mongodb 連接字串規範。
- 緩衝
- 錯誤處理
- 選項
- serverSelectionTimeoutMS
- 連接字串選項
- 連線事件
- 關於 keepAlive 的注意事項
- 伺服器選擇
- 複本集連線
- 複本集主機名稱
- 多個 mongos 支援
- 多個連線
- 連線池
- 多租戶連線
操作緩衝
Mongoose 可讓您立即開始使用模型,無需等待 Mongoose 建立與 MongoDB 的連線。
mongoose.connect('mongodb://127.0.0.1:27017/myapp');
const MyModel = mongoose.model('Test', new Schema({ name: String }));
// Works
await MyModel.findOne();
這是因為 Mongoose 會在內部緩衝模型函式呼叫。此緩衝很方便,但也是常見的混淆來源。如果您在未連線的情況下使用模型,Mongoose 預設情況下不會擲回任何錯誤。
const MyModel = mongoose.model('Test', new Schema({ name: String }));
const promise = MyModel.findOne();
setTimeout(function() {
mongoose.connect('mongodb://127.0.0.1:27017/myapp');
}, 60000);
// Will just hang until mongoose successfully connects
await promise;
若要停用緩衝,請關閉綱要上的 bufferCommands
選項。如果您已開啟 bufferCommands
且連線停滯,請嘗試關閉 bufferCommands
,以查看是否已正確開啟連線。您也可以全域停用 bufferCommands
mongoose.set('bufferCommands', false);
請注意,如果您使用 autoCreate
選項,緩衝也負責等待 Mongoose 建立集合。如果您停用緩衝,也應該停用 autoCreate
選項,並使用 createCollection()
來建立上限集合或具有定序的集合。
const schema = new Schema({
name: String
}, {
capped: { size: 1024 },
bufferCommands: false,
autoCreate: false // disable `autoCreate` since `bufferCommands` is false
});
const Model = mongoose.model('Test', schema);
// Explicitly create the collection before using it
// so the collection is capped.
await Model.createCollection();
錯誤處理
Mongoose 連線可能會發生兩種類型的錯誤。
- 初始連線時發生錯誤:如果初始連線失敗,Mongoose 會發出 'error' 事件,且
mongoose.connect()
傳回的 Promise 會拒絕。但是,Mongoose 不會自動嘗試重新連線。 - 建立初始連線後發生錯誤:Mongoose 會嘗試重新連線,並發出 'error' 事件。
若要處理初始連線錯誤,您應該使用 .catch()
或 try/catch
與 async/await。
mongoose.connect('mongodb://127.0.0.1:27017/test').
catch(error => handleError(error));
// Or:
try {
await mongoose.connect('mongodb://127.0.0.1:27017/test');
} catch (error) {
handleError(error);
}
若要處理建立初始連線後發生的錯誤,您應該接聽連線上的錯誤事件。但是,您仍然需要如上所示處理初始連線錯誤。
mongoose.connection.on('error', err => {
logError(err);
});
請注意,如果 Mongoose 失去與 MongoDB 的連線能力,不一定會發出 'error' 事件。您應該接聽 disconnected
事件,以回報 Mongoose 何時與 MongoDB 斷線。
選項
connect
方法也接受 options
物件,該物件將傳遞至底層 MongoDB 驅動程式。
mongoose.connect(uri, options);
完整的選項清單可在 MongoDB Node.js 驅動程式文件中找到 MongoClientOptions
。Mongoose 會將選項傳遞至驅動程式,而不進行修改,但以下說明的一些例外情況除外。
bufferCommands
- 這是一個 Mongoose 特有的選項 (不會傳遞至 MongoDB 驅動程式),可停用Mongoose 的緩衝機制user
/pass
- 用於驗證的使用者名稱和密碼。這些選項是 Mongoose 特有的,相當於 MongoDB 驅動程式的auth.username
和auth.password
選項。autoIndex
- 依預設,Mongoose 會在連線時自動建置綱要中定義的索引。這對於開發非常有用,但不適合大型生產部署,因為索引建置可能會導致效能下降。如果將autoIndex
設定為 false,Mongoose 將不會自動建置與此連線相關聯的任何模型的索引。dbName
- 指定要連線的資料庫,並覆寫連接字串中指定的任何資料庫。如果您無法在連接字串中指定預設資料庫,例如 某些mongodb+srv
語法連線,這會很有用。
以下是一些對於調整 Mongoose 很重要的選項。
promiseLibrary
- 設定底層驅動程式的 Promise 程式庫。maxPoolSize
- MongoDB 驅動程式會為此連線保持開啟的最大 Socket 數。依預設,maxPoolSize
為 100。請記住,MongoDB 一次只允許每個 Socket 執行一個操作,因此如果您發現有一些慢速查詢會阻礙較快的查詢繼續進行,您可能需要增加此值。請參閱MongoDB 和 Node.js 中的慢速列車。如果您遇到連線限制,您可能需要減少maxPoolSize
。minPoolSize
- MongoDB 驅動程式會為此連線保持開啟的最小 Socket 數。MongoDB 驅動程式可能會關閉已閒置一段時間的 Socket。如果您預期應用程式會經歷長時間的閒置時間,且想要確保 Socket 保持開啟以避免活動增加時出現慢速列車,您可能需要增加minPoolSize
。socketTimeoutMS
- 在初始連線之後,MongoDB 驅動程式因閒置而終止 Socket 之前等待的時間長度。Socket 可能因為沒有活動或長時間執行的操作而處於閒置狀態。socketTimeoutMS
預設值為 0,表示 Node.js 不會因閒置而導致 Socket 超時。此選項會在 MongoDB 驅動程式成功完成後,傳遞至 Node.jssocket#setTimeout()
函式。family
- 是否使用 IPv4 或 IPv6 連線。此選項會傳遞至 Node.js 的dns.lookup()
函式。如果您未指定此選項,MongoDB 驅動程式會先嘗試 IPv6,如果 IPv6 失敗,則會嘗試 IPv4。如果您的mongoose.connect(uri)
呼叫需要很長時間,請嘗試mongoose.connect(uri, { family: 4 })
authSource
- 使用user
和pass
進行驗證時要使用的資料庫。在 MongoDB 中,使用者會以資料庫為範圍。如果您遇到意外的登入失敗,您可能需要設定此選項。serverSelectionTimeoutMS
- MongoDB 驅動程式會嘗試尋找要將任何指定操作傳送到的伺服器,並在serverSelectionTimeoutMS
毫秒內持續重試。如果未設定,MongoDB 驅動程式預設會使用30000
(30 秒)。heartbeatFrequencyMS
- MongoDB 驅動程式會每隔heartbeatFrequencyMS
發送一個心跳訊號,以檢查連線狀態。心跳訊號會受到serverSelectionTimeoutMS
的約束,因此 MongoDB 驅動程式預設會將失敗的心跳訊號重試最多 30 秒。Mongoose 只會在心跳訊號失敗後發出'disconnected'
事件,因此您可能需要縮短此設定,以減少伺服器關閉與 Mongoose 發出'disconnected'
之間的時間。我們建議您不要將此設定設定為低於 1000,過多的心跳訊號可能會導致效能下降。
serverSelectionTimeoutMS
serverSelectionTimeoutMS
選項非常重要:它控制 MongoDB Node.js 驅動程式在發生錯誤之前嘗試重試任何操作的時間長度。這包括初始連線 (例如 await mongoose.connect()
),以及對 MongoDB 發出請求的任何操作 (例如 save()
或 find()
)。
依預設,serverSelectionTimeoutMS
為 30000 (30 秒)。這表示,例如,如果您在獨立 MongoDB 伺服器關閉時呼叫 mongoose.connect()
,您的 mongoose.connect()
呼叫只會在 30 秒後擲回錯誤。
// Throws an error "getaddrinfo ENOTFOUND doesnt.exist" after 30 seconds
await mongoose.connect('mongodb://doesnt.exist:27017/test');
同樣地,如果您的獨立 MongoDB 伺服器在初始連線後關閉,任何 find()
或 save()
呼叫都會在 30 秒後發生錯誤,除非您的 MongoDB 伺服器重新啟動。
雖然 30 秒似乎很長,但 serverSelectionTimeoutMS
表示您不太可能在複本集容錯移轉期間看到任何中斷。如果您遺失複本集主要節點,MongoDB Node 驅動程式將確保您在複本集選舉期間傳送的任何操作最終都會執行,前提是複本集選舉花費的時間少於 serverSelectionTimeoutMS
。
為了在連線失敗時獲得更快速的回饋,您可以將 serverSelectionTimeoutMS
減少至 5000,如下所示。除非您執行的是獨立 MongoDB 伺服器而不是複本集,或是除非您使用的是無伺服器執行階段 (例如AWS Lambda),否則我們不建議減少 serverSelectionTimeoutMS
。
mongoose.connect(uri, {
serverSelectionTimeoutMS: 5000
});
無法為 mongoose.connect()
和查詢獨立調整 serverSelectionTimeoutMS
。如果您想要縮短查詢和其他操作的 serverSelectionTimeoutMS
,但仍想要將 mongoose.connect()
的重試時間延長,您有責任自行使用 for
迴圈或類似 p-retry 的工具重試 connect()
呼叫。
const serverSelectionTimeoutMS = 5000;
// Prints "Failed 0", "Failed 1", "Failed 2" and then throws an
// error. Exits after approximately 15 seconds.
for (let i = 0; i < 3; ++i) {
try {
await mongoose.connect('mongodb://doesnt.exist:27017/test', {
serverSelectionTimeoutMS
});
break;
} catch (err) {
console.log('Failed', i);
if (i >= 2) {
throw err;
}
}
}
回呼
connect()
函式也接受回呼參數,並傳回 promise。
mongoose.connect(uri, options, function(error) {
// Check error in initial connection. There is no 2nd param to the callback.
});
// Or using promises
mongoose.connect(uri, options).then(
() => { /** ready to use. The `mongoose.connect()` promise resolves to mongoose instance. */ },
err => { /** handle initial connection error */ }
);
連接字串選項
您也可以在連線字串中將驅動程式選項指定為 URI 的查詢字串部分中的參數。這僅適用於傳遞至 MongoDB 驅動程式的選項。您無法在查詢字串中設定 Mongoose 特有的選項 (例如 bufferCommands
)。
mongoose.connect('mongodb://127.0.0.1:27017/test?socketTimeoutMS=1000&bufferCommands=false&authSource=otherdb');
// The above is equivalent to:
mongoose.connect('mongodb://127.0.0.1:27017/test', {
socketTimeoutMS: 1000
// Note that mongoose will **not** pull `bufferCommands` from the query string
});
將選項放入查詢字串的缺點是查詢字串選項較難閱讀。優點是您只需要單一組態選項 (URI),而不是 socketTimeoutMS
等個別選項。最佳做法是將開發和生產之間可能不同的選項 (例如 replicaSet
或 ssl
) 放在連接字串中,而將應該保持不變的選項 (例如 socketTimeoutMS
或 maxPoolSize
) 放在選項物件中。
MongoDB 文件包含支援的連接字串選項的完整清單。以下是一些通常適合在連接字串中設定的選項,因為它們與主機名稱和驗證資訊密切相關。
authSource
- 使用user
和pass
進行驗證時要使用的資料庫。在 MongoDB 中,使用者會以資料庫為範圍。如果您遇到意外的登入失敗,您可能需要設定此選項。family
- 是否使用 IPv4 或 IPv6 連線。此選項會傳遞至 Node.js 的dns.lookup()
函式。如果您未指定此選項,MongoDB 驅動程式會先嘗試 IPv6,如果 IPv6 失敗,則會嘗試 IPv4。如果您的mongoose.connect(uri)
呼叫需要很長時間,請嘗試mongoose.connect(uri, { family: 4 })
連線事件
連線繼承自 Node.js 的 EventEmitter
類別,並在連線發生某些情況時發出事件,例如失去與 MongoDB 伺服器的連線能力。以下是連線可能會發出的事件清單。
connecting
:當 Mongoose 開始建立與 MongoDB 伺服器的初始連線時發出connected
:當 Mongoose 成功建立與 MongoDB 伺服器的初始連線,或當 Mongoose 在失去連線能力後重新連線時發出。如果 Mongoose 失去連線能力,可能會發出多次。open
:在'connected'
之後發出,並在此連線的所有模型上執行onOpen
。如果 Mongoose 失去連線能力,可能會發出多次。disconnecting
:您的應用程式呼叫Connection#close()
以與 MongoDB 斷線。這包括呼叫mongoose.disconnect()
,它會對所有連線呼叫close()
。disconnected
:當 Mongoose 與 MongoDB 伺服器的連線中斷時發出。此事件可能是由於您的程式碼明確關閉連線、資料庫伺服器崩潰或網路連線問題所導致。close
:在Connection#close()
成功關閉連線後發出。如果您呼叫conn.close()
,您將會同時收到 'disconnected' 和 'close' 事件。reconnected
:如果 Mongoose 與 MongoDB 的連線中斷,並成功重新連線時發出。當 Mongoose 與資料庫失去連線時,會嘗試自動重新連線。error
:如果連線上發生錯誤時發出,例如由於資料格式錯誤導致的parseError
或有效負載大於16MB。
當您連線到單一 MongoDB 伺服器(一個「獨立」伺服器)時,如果 Mongoose 與獨立伺服器斷線,則會發出 disconnected
事件;如果成功連線到獨立伺服器,則會發出 connected
事件。在副本集中,如果 Mongoose 與副本集主節點失去連線,則會發出 disconnected
事件;如果成功重新連線到副本集主節點,則會發出 connected
事件。
如果您使用 mongoose.connect()
,您可以使用以下方式來監聽上述事件
mongoose.connection.on('connected', () => console.log('connected'));
mongoose.connection.on('open', () => console.log('open'));
mongoose.connection.on('disconnected', () => console.log('disconnected'));
mongoose.connection.on('reconnected', () => console.log('reconnected'));
mongoose.connection.on('disconnecting', () => console.log('disconnecting'));
mongoose.connection.on('close', () => console.log('close'));
mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test');
使用 mongoose.createConnection()
,請改用以下方式
const conn = mongoose.createConnection('mongodb://127.0.0.1:27017/mongoose_test');
conn.on('connected', () => console.log('connected'));
conn.on('open', () => console.log('open'));
conn.on('disconnected', () => console.log('disconnected'));
conn.on('reconnected', () => console.log('reconnected'));
conn.on('disconnecting', () => console.log('disconnecting'));
conn.on('close', () => console.log('close'));
關於 keepAlive 的注意事項
在 Mongoose 5.2.0 之前,您需要啟用 keepAlive
選項來啟動 TCP keepalive,以防止 "connection closed"
錯誤。然而,自 Mongoose 5.2.0 以來,keepAlive
預設為 true
,且 keepAlive
自 Mongoose 7.2.0 起已棄用。請從您的 Mongoose 連線中移除 keepAlive
和 keepAliveInitialDelay
選項。
複本集連線
若要連線到副本集,您需要傳遞以逗號分隔的主機列表,而不是單一主機。
mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);
例如
mongoose.connect('mongodb://user:pw@host1.com:27017,host2.com:27017,host3.com:27017/testdb');
若要連線到單一節點副本集,請指定 replicaSet
選項。
mongoose.connect('mongodb://host1:port1/?replicaSet=rsName');
伺服器選擇
底層的 MongoDB 驅動程式使用一種稱為伺服器選擇的程序來連線到 MongoDB 並將操作發送到 MongoDB。如果 MongoDB 驅動程式在 serverSelectionTimeoutMS
之後找不到伺服器來發送操作,您將會收到以下錯誤
您可以使用 mongoose.connect()
的 serverSelectionTimeoutMS
選項來設定逾時時間。
mongoose.connect(uri, {
serverSelectionTimeoutMS: 5000 // Timeout after 5s instead of 30s
});
MongoTimeoutError
具有一個 reason
屬性,可以解釋為何伺服器選擇逾時。例如,如果您使用不正確的密碼連線到獨立伺服器,reason
將會包含一個「Authentication failed」錯誤。
const mongoose = require('mongoose');
const uri = 'mongodb+srv://username:badpw@cluster0-OMITTED.mongodb.net/' +
'test?retryWrites=true&w=majority';
// Prints "MongoServerError: bad auth Authentication failed."
mongoose.connect(uri, {
serverSelectionTimeoutMS: 5000
}).catch(err => console.log(err.reason));
複本集主機名稱
MongoDB 副本集依賴於能夠可靠地找出每個成員的網域名稱。
在 Linux 和 OSX 上,MongoDB 伺服器使用 hostname
命令的輸出,來找出要回報給副本集的網域名稱。如果您連線到執行在將其 hostname
回報為 localhost
的機器上的遠端 MongoDB 副本集,可能會導致令人困惑的錯誤
// Can get this error even if your connection string doesn't include
// `localhost` if `rs.conf()` reports that one replica set member has
// `localhost` as its host name.
MongooseServerSelectionError: connect ECONNREFUSED localhost:27017
如果您遇到類似的錯誤,請使用 mongo
shell 連線到副本集,並執行 rs.conf()
命令來檢查每個副本集成員的主機名稱。請依照 此頁面的指示來變更副本集成員的主機名稱。
您也可以檢查 MongooseServerSelectionError
的 reason.servers
屬性,以查看 MongoDB Node 驅動程式認為您的副本集的狀態是什麼。reason.servers
屬性包含一個伺服器描述的 map。
if (err.name === 'MongooseServerSelectionError') {
// Contains a Map describing the state of your replica set. For example:
// Map(1) {
// 'localhost:27017' => ServerDescription {
// address: 'localhost:27017',
// type: 'Unknown',
// ...
// }
// }
console.log(err.reason.servers);
}
多個 mongos 支援
您還可以連線到多個 mongos 實例,以在分片叢集中實現高可用性。在 Mongoose 5.x 中,您不需要傳遞任何特殊選項即可連線到多個 mongos。
// Connect to 2 mongos servers
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', cb);
多個連線
到目前為止,我們已經了解如何使用 Mongoose 的預設連線連線到 MongoDB。當您呼叫 mongoose.connect()
時,Mongoose 會建立一個預設連線。您可以使用 mongoose.connection
來存取預設連線。
您可能需要多個與 MongoDB 的連線,原因有很多。其中一個原因是如果您有多個資料庫或多個 MongoDB 叢集。另一個原因是要解決慢列車的問題。mongoose.createConnection()
函數接受與 mongoose.connect()
相同的參數,並傳回一個新的連線。
const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
這個連線物件隨後會用於建立和檢索模型。模型總是被限制在單一連線的範圍內。
const UserModel = conn.model('User', userSchema);
createConnection()
函數會傳回一個連線實例,而不是一個 Promise。如果您想使用 await
來確保 Mongoose 成功連線到 MongoDB,請使用 asPromise()
函數。
// `asPromise()` returns a promise that resolves to the connection
// once the connection succeeds, or rejects if connection failed.
const conn = await mongoose.createConnection(connectionString).asPromise();
如果您使用多個連線,您應該確保匯出 schema,而不是 models。從檔案匯出 model 稱為匯出 model 模式。匯出 model 模式受到限制,因為您只能使用一個連線。
const userSchema = new Schema({ name: String, email: String });
// The alternative to the export model pattern is the export schema pattern.
module.exports = userSchema;
// Because if you export a model as shown below, the model will be scoped
// to Mongoose's default connection.
// module.exports = mongoose.model('User', userSchema);
如果您使用匯出 schema 模式,您仍然需要在某個地方建立模型。有兩種常見的模式。第一種是建立一個函數,該函數會實例化一個新的連線,並在該連線上註冊所有模型。使用這種模式,您也可以使用依賴注入器或其他控制反轉 (IOC) 模式來註冊連線。
const mongoose = require('mongoose');
module.exports = function connectionFactory() {
const conn = mongoose.createConnection(process.env.MONGODB_URI);
conn.model('User', require('../schemas/user'));
conn.model('PageView', require('../schemas/pageView'));
return conn;
};
匯出一個建立新連線的函數是最具彈性的模式。然而,這種模式可能會使您難以從您的路由處理程式或您的業務邏輯所在的位置存取連線。另一種模式是匯出一個連線,並在檔案的頂層範圍中註冊連線上的模型,如下所示。
// connections/index.js
const mongoose = require('mongoose');
const conn = mongoose.createConnection(process.env.MONGODB_URI);
conn.model('User', require('../schemas/user'));
module.exports = conn;
如果您想為您的 Web API 後端和行動 API 後端建立單獨的連線,您可以為每個連線建立單獨的檔案,例如 connections/web.js
和 connections/mobile.js
。您的業務邏輯隨後可以 require()
或 import
它需要的連線。
連線池
每個 connection
,無論是使用 mongoose.connect
還是 mongoose.createConnection
建立的,都由一個內部可配置的連線池支援,預設最大大小為 100。使用您的連線選項來調整池大小
// With object options
mongoose.createConnection(uri, { maxPoolSize: 10 });
// With connection string options
const uri = 'mongodb://127.0.0.1:27017/test?maxPoolSize=10';
mongoose.createConnection(uri);
連線池大小很重要,因為MongoDB 目前每個 socket 只能處理一個操作。因此 maxPoolSize
作為並行操作數量的上限。
多租戶連線
在 Mongoose 的情境中,多租戶架構通常表示多個不同的客戶端透過單一 Mongoose 應用程式與 MongoDB 通訊的情況。這通常表示每個客戶端透過單一 Mongoose 應用程式發出查詢並執行更新,但在同一個 MongoDB 叢集中具有不同的 MongoDB 資料庫。
我們建議閱讀這篇關於使用 Mongoose 的多租戶的文章;它很好地描述了我們如何定義多租戶,並更詳細地概述了我們建議的模式。
我們建議在 Mongoose 中使用兩種模式進行多租戶
- 維護一個連線池,使用
Connection.prototype.useDb()
方法在租戶之間切換。 - 為每個租戶維護單獨的連線池,將連線儲存在 map 或 POJO 中。
以下是模式 (1) 的範例。我們建議在租戶數量很少的情況下,或者如果每個個別租戶的工作負載很輕(大約 < 每秒 1 個請求,所有請求的資料庫處理時間都 < 10 毫秒)使用模式 (1)。模式 (1) 更容易實作且更容易在生產環境中管理,因為只有 1 個連線池。但是,在高負載下,您很可能會遇到一些租戶的操作由於慢列車而減慢其他租戶的操作的問題。
const express = require('express');
const mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/main');
mongoose.set('debug', true);
mongoose.model('User', mongoose.Schema({ name: String }));
const app = express();
app.get('/users/:tenantId', function(req, res) {
const db = mongoose.connection.useDb(`tenant_${req.params.tenantId}`, {
// `useCache` tells Mongoose to cache connections by database name, so
// `mongoose.connection.useDb('foo', { useCache: true })` returns the
// same reference each time.
useCache: true
});
// Need to register models every time a new connection is created
if (!db.models['User']) {
db.model('User', mongoose.Schema({ name: String }));
}
console.log('Find users from', db.name);
db.model('User').find().
then(users => res.json({ users })).
catch(err => res.status(500).json({ message: err.message }));
});
app.listen(3000);
以下是模式 (2) 的範例。模式 (2) 更靈活,更適合用於 > 1 萬個租戶和 > 每秒 1 個請求的用例。由於每個租戶都有一個單獨的連線池,因此一個租戶的慢速操作對其他租戶的影響最小。但是,此模式更難以實作和管理。特別是,MongoDB 對於開啟的連線數量確實有限制,並且MongoDB Atlas 對於開啟的連線數量也有單獨的限制,因此您需要確保連線池中的 socket 總數不會超過 MongoDB 的限制。
const express = require('express');
const mongoose = require('mongoose');
const tenantIdToConnection = {};
const app = express();
app.get('/users/:tenantId', function(req, res) {
let initialConnection = Promise.resolve();
const { tenantId } = req.params;
if (!tenantIdToConnection[tenantId]) {
tenantIdToConnection[tenantId] = mongoose.createConnection(`mongodb://127.0.0.1:27017/tenant_${tenantId}`);
tenantIdToConnection[tenantId].model('User', mongoose.Schema({ name: String }));
initialConnection = tenantIdToConnection[tenantId].asPromise();
}
const db = tenantIdToConnection[tenantId];
initialConnection.
then(() => db.model('User').find()).
then(users => res.json({ users })).
catch(err => res.status(500).json({ message: err.message }));
});
app.listen(3000);
下一步
既然我們已經介紹了連線,讓我們來看看模型。