MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

La topologie a été détruite lors de l'utilisation de MongoDB avec un pilote natif et Express.js

En effet, le code contient un anti-modèle :chaque fois qu'une nouvelle requête arrive, il ouvre une nouvelle connexion à la base de données, puis ferme cette connexion une fois la réponse envoyée. Il a ensuite tenté de réutiliser la connexion fermée, d'où le message d'erreur que vous voyez à la 2ème requête.

Ce que vous voulez, c'est vous connecter une seule fois à la base de données pendant toute la durée de vie de l'application à l'aide d'un objet de connexion global, puis utiliser cet objet global pour effectuer vos opérations de base de données.

L'utilisation de cet objet global permet au pilote MongoDB de créer correctement un pool de connexions à la base de données. Ce pool est géré par le pilote MongoDB et évite le coûteux modèle de connexion/reconnexion.

Par exemple :

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

Modifier pour répondre à ta question en commentaire :

En effet, dans le code d'origine, dbClient a été définie globalement. Lorsque dbClient.close() a été appelé, le dbClient global était fermé. Une erreur s'est alors produite lorsque ce dbClient l'objet a été réutilisé. C'est parce que connect() crée un pool de connexions au lieu d'une seule connexion et n'était pas censé être appelé plusieurs fois par invocation.

Si vous déplacez le dbClient variable de la portée globale dans app.get() contexte, vous constaterez qu'aucune erreur ne sera produite lorsque vous appelez le point de terminaison HTTP plusieurs fois, en tant que nouveau dbClient l'objet a été créé à chaque fois.

Cela dit, bien que cela fonctionne, ce n'est pas un modèle recommandé. Il est préférable d'utiliser un modèle similaire à l'exemple de code que j'ai posté ci-dessus.