sql >> Base de Datos >  >> NoSQL >> MongoDB

La topología se destruyó al usar MongoDB con el controlador nativo y Express.js

Esto se debe a que el código contiene un antipatrón:cada vez que ingresa una nueva solicitud, abre una nueva conexión de base de datos y luego cierra esa conexión una vez que se envía la respuesta. Posteriormente, intentó reutilizar la conexión cerrada, de ahí el mensaje de error que está viendo en la segunda solicitud.

Lo que desea es conectarse solo una vez a la base de datos durante la vida útil de la aplicación utilizando un objeto de conexión global, luego use ese objeto global para realizar sus operaciones de base de datos.

El uso de este objeto global permite que el controlador MongoDB cree correctamente un grupo de conexiones a la base de datos. Este grupo es administrado por el controlador MongoDB y evita el costoso patrón de conexión/reconexión.

Por ejemplo:

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

Editar para responder a su pregunta en el comentario:

Esto se debe a que en el código original, dbClient se definió globalmente. Cuando dbClient.close() fue llamado, el dbClient global estaba cerrado. Luego se produjo un error cuando ese dbClient el objeto fue reutilizado. Esto se debe a que connect() crea un grupo de conexiones en lugar de una única conexión y no se esperaba que se llamara varias veces por invocación.

Si mueve el dbClient variable desde el alcance global al app.get() contexto, encontrará que no se producirá ningún error cuando llame al punto final HTTP varias veces, como un nuevo dbClient el objeto fue creado cada vez.

Habiendo dicho eso, aunque funcionará, este no es un patrón recomendado. Es mejor usar un patrón similar al código de ejemplo que publiqué anteriormente.