これは、コードにアンチパターンが含まれているためです。新しいリクエストが着信するたびに、新しいデータベース接続が開かれ、応答が送信されるとその接続が閉じられます。その後、閉じた接続を再利用しようとしたため、2番目のリクエストに表示されるエラーメッセージが表示されます。
必要なのは、グローバル接続オブジェクトを使用してアプリケーションの存続期間中1回だけデータベースに接続し、次にそのグローバルオブジェクトを使用してデータベース操作を実行することです。
このグローバルオブジェクトを使用すると、MongoDBドライバーはデータベースへの接続プールを適切に作成できます。このプールはMongoDBドライバーによって管理され、高価な接続/再接続パターンを回避します。
例:
// listen on this port
const port = 3000
// global database client object
var client = null
// listen on the configured port once database connection is established
MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true }, (err, res) => {
assert.equal(null, err)
client = res
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
})
// use the client global object for database operations
app.get('/', (req, res) => {
db = req.query.db
col = req.query.col
client.db(db).collection(col).find({}).toArray((err, docs) => {
assert.equal(null, err)
res.send(JSON.stringify(docs))
})
})
編集 コメントであなたの質問に答えるには:
これは、元のコードではdbClient
が原因であるため、 グローバルに定義されました。 dbClient.close()
の場合 呼び出された、グローバルdbClient
閉鎖されました。そのdbClient
のときに、エラーが生成されました。 オブジェクトが再利用されました。これは、connect()
が原因です。 単一の接続ではなく接続プールを作成し、呼び出しごとに複数回呼び出されることは想定されていませんでした。
dbClient
を移動した場合 グローバルスコープからapp.get()
への変数 コンテキストでは、新しいdbClient
としてHTTPエンドポイントを複数回呼び出しても、エラーは発生しないことがわかります。 オブジェクトは毎回作成されました。
そうは言っても、それは機能しますが、これは推奨されるパターンではありません。上で投稿したサンプルコードに似たパターンを使用することをお勧めします。