代码之家  ›  专栏  ›  技术社区  ›  V_V

使用MongoDB和本机驱动程序和Express.js时,“拓扑被破坏”

  •  0
  • V_V  · 技术社区  · 7 年前

    const express = require('express')
    const app = express()
    const port = 3000
    
    const MongoClient = require('mongodb').MongoClient;
    const assert = require('assert');
    
    const dbConnectionURL = 'mongodb://localhost:27017';
    const dbName = 'todo';
    const dbClient = new MongoClient(dbConnectionURL);
    
    function findTodos(db, callback) {
        const collection = db.collection('todos');
        collection.find({}).toArray(function (err, todos) {
            assert.equal(err, null);
            console.log("Found the following records");
            console.log(todos)
            callback(todos);
        });
    }
    
    app.get('/', (req, res) => {
        dbClient.connect(function (err) {
            assert.equal(null, err);
            console.log("Connected successfully to server");
    
            const db = dbClient.db(dbName);
    
            findTodos(db, function(todosArr) {
                var todos = { todos: todosArr }
                res.send(todos)
                dbClient.close()
            });
        });
    });
    
    app.listen(port, () => console.log(`Example app listening on port ${port}!`))
    

    它基本上是复制粘贴在线教程。我第一次向' http://localhost:3000/

    todo-backend/node_modules/mongodb/lib/utils.js:132
        throw err;
        ^
    
    AssertionError [ERR_ASSERTION]: 'MongoError: Topology was destroyed' == null
        at todo-backend/index.js:15:16
        at err (todo-backend/node_modules/mongodb/lib/utils.js:415:14)
        at executeCallback (todo-backend/node_modules/mongodb/lib/utils.js:404:25)
        at handleCallback (todo-backend/node_modules/mongodb/lib/utils.js:128:55)
        at cursor._endSession.cursor._endSession (todo-backend/node_modules/mongodb/lib/operations/cursor_ops.js:207:38)
        at ClientSession.endSession (todo-backend/node_modules/mongodb-core/lib/sessions.js:129:41)
        at Cursor._endSession (todo-backend/node_modules/mongodb-core/lib/cursor.js:189:13)
        at Cursor._endSession (todo-backend/node_modules/mongodb/lib/cursor.js:226:59)
        at cursor._next (todo-backend/node_modules/mongodb/lib/operations/cursor_ops.js:207:20)
        at initializeCursor (todo-backend/node_modules/mongodb-core/lib/cursor.js:766:16)
    

    我在网上寻找答案,发现了类似的错误,但当人们做更复杂的事情时。我所做的似乎更基本,我找不到任何可能有帮助的改变空间。

    如果我移除 dbClient.close() 它可以工作,但是我在MongoDB日志中看到连接的数量在不断增长。当然,我可以引入一个标志并检查我是否已经连接。但对于这个问题,我想了解一个根本原因。

    1 回复  |  直到 7 年前
        1
  •  14
  •   kevinadi    7 年前

    使用这个全局对象允许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() 被称为全球 数据库客户端 已经关门了。然后,在执行该操作时产生了一个错误 数据库客户端 connect() 创建连接池而不是单个连接,并且不希望每次调用都调用多次。

    如果你移动 从全局范围到 app.get() 在上下文中,您会发现当您多次调用HTTP端点时,不会产生任何错误,作为一个新的端点 每次都创建对象。

    话虽如此,但这并不是一种推荐的模式。最好使用类似于我上面发布的示例代码的模式。

        2
  •  0
  •   Ajay    5 年前

    我在mongoDB内部进行了一些配置更改,保持访问ip不变时遇到了同样的问题。

    我只需重新启动访问mongoDB的服务器就解决了这个问题。

    推荐文章