MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

La topologia è stata distrutta durante l'utilizzo di MongoDB con driver nativo ed Express.js

Questo perché il codice contiene un anti-pattern:ogni volta che arriva una nuova richiesta, apre una nuova connessione al database, quindi chiude quella connessione una volta inviata la risposta. Successivamente ha provato a riutilizzare la connessione chiusa, da cui il messaggio di errore che viene visualizzato alla seconda richiesta.

Quello che vuoi è connetterti solo una volta al database per tutta la durata dell'applicazione utilizzando un oggetto di connessione globale, quindi utilizzare quell'oggetto globale per eseguire le operazioni del database.

L'utilizzo di questo oggetto globale consente al driver MongoDB di creare correttamente un pool di connessioni al database. Questo pool è gestito dal driver MongoDB ed evita il costoso schema di connessione/riconnessione.

Ad esempio:

// 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))
  })
})

Modifica per rispondere alla tua domanda nel commento:

Questo perché nel codice originale, dbClient era definito a livello globale. Quando dbClient.close() è stato chiamato, il globale dbClient era chiuso. È stato quindi prodotto un errore quando quel dbClient oggetto è stato riutilizzato. Questo perché connect() crea un pool di connessioni invece di una singola connessione e non doveva essere chiamato più volte per chiamata.

Se sposti dbClient variabile dall'ambito globale in app.get() contesto, scoprirai che non verrà prodotto alcun errore quando chiami l'endpoint HTTP più volte, come nuovo dbClient l'oggetto è stato creato ogni volta.

Detto questo, anche se funzionerà, questo non è uno schema consigliato. È meglio usare un modello simile al codice di esempio che ho pubblicato sopra.