MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Die Topologie wurde bei Verwendung von MongoDB mit nativem Treiber und Express.js zerstört

Das liegt daran, dass der Code ein Anti-Pattern enthält:Jedes Mal, wenn eine neue Anfrage eingeht, öffnet er eine neue Datenbankverbindung und schließt diese Verbindung, sobald die Antwort gesendet wurde. Es hat dann anschließend versucht, die geschlossene Verbindung wiederzuverwenden, daher die Fehlermeldung, die Sie bei der zweiten Anfrage sehen.

Was Sie möchten, ist, sich nur einmal für die Lebensdauer der Anwendung mit einem globalen Verbindungsobjekt mit der Datenbank zu verbinden und dann dieses globale Objekt zu verwenden, um Ihre Datenbankoperationen auszuführen.

Durch die Verwendung dieses globalen Objekts kann der MongoDB-Treiber ordnungsgemäß einen Verbindungspool zur Datenbank erstellen. Dieser Pool wird vom MongoDB-Treiber verwaltet und vermeidet das teure Connect/Reconnect-Muster.

Zum Beispiel:

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

Bearbeiten um deine Frage im Kommentar zu beantworten:

Dies liegt daran, dass im Originalcode dbClient wurde global definiert. Wenn dbClient.close() aufgerufen wurde, der globale dbClient war geschlossen. Dann wurde ein Fehler erzeugt, wenn dbClient Objekt wurde wiederverwendet. Das liegt daran, dass connect() erstellt einen Verbindungspool anstelle einer einzelnen Verbindung und sollte nicht mehrmals pro Aufruf aufgerufen werden.

Wenn Sie den dbClient verschieben Variable aus dem globalen Gültigkeitsbereich in app.get() Kontext, werden Sie feststellen, dass kein Fehler erzeugt wird, wenn Sie den HTTP-Endpunkt mehrmals als neuen dbClient aufrufen Objekt wurde jedes Mal erstellt.

Obwohl es funktionieren wird, ist dies jedoch kein empfohlenes Muster. Es ist besser, ein Muster zu verwenden, das dem Beispielcode ähnelt, den ich oben gepostet habe.