You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Express应用调用MongoDB时遇TypeError问题求助

问题描述

在Docker上运行Express应用时,访问localhost:3000/createMongo或localhost:3000/readMongo会触发以下错误:

TypeError: Cannot read properties of undefined (reading 'collection')
    at /app/index.js:24:25
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/app/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/app/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
    at /app/node_modules/express/lib/router/index.js:284:15
    at Function.process_params (/app/node_modules/express/lib/router/index.js:346:12)
    at next (/app/node_modules/express/lib/router/index.js:280:10)
    at expressInit (/app/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)

补充说明:访问localhost:3000可正常显示Greetings from the server!!,控制台也输出Connected correctly to server!!,推测是MongoDB更新后语法不兼容导致。

原index.js代码:

var express     = require('express');
var app         = express();
var MongoClient = require('mongodb').MongoClient;

// the name "mongo" comes from the docker link, in the docker-compose.yml
var url = 'mongodb://mongo:27017/dockerdemo';
var db;

MongoClient.connect(url, function (err, database) {
    if(err){ console.log('failed to connect: ' + err); return;}
    db = database;
    console.log("Connected correctly to server!!");
});

app.get('/', function(req, res){
    res.send('Greetings from the server!!');
});

app.get('/createMongo', function(req, res){ 

    var name = 'user' + Math.floor(Math.random()*10000);
    var email = name + '@mit.edu';

    var collection = db.collection('customers');
    var doc = {'name':name, 'email':email};
    collection.insert(doc, {w:1}, function(err, result) {
        console.dir(result);
        res.send(result);
    });      
});


app.get('/readMongo', function(req, res){  

    var results = null;    
    var collection = db
        .collection('customers')
        .find()
        .toArray(function(err, docs) {
            console.dir(docs);
            res.send(docs);
    });
});



app.listen(3000);
问题排查与解决

错误原因

  1. MongoDB驱动版本兼容问题:MongoDB Node.js驱动v3+版本中,MongoClient.connect的回调参数不再直接返回数据库实例,而是返回客户端对象,需要通过client.db()获取目标数据库。原代码直接将回调的database赋值给db,实际拿到的是客户端对象,并非数据库实例,导致调用db.collection()时出错。
  2. 弃用API使用:collection.insert()方法已被弃用,需替换为insertOne(单文档插入)或insertMany(多文档插入)。
  3. 连接未就绪时的请求风险:原代码未处理MongoDB连接完成前的请求,若在连接建立前访问/createMongo或/readMongo,db变量仍为undefined,也会触发错误。

修复后的代码

var express     = require('express');
var app         = express();
var MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://mongo:27017/dockerdemo';
var db;

// 修正连接逻辑,获取正确的数据库实例
MongoClient.connect(url, function (err, client) {
    if(err){ 
        console.log('failed to connect: ' + err); 
        return;
    }
    // 通过client.db()获取目标数据库
    db = client.db('dockerdemo');
    console.log("Connected correctly to server!!");
});

app.get('/', function(req, res){
    res.send('Greetings from the server!!');
});

app.get('/createMongo', function(req, res){ 
    // 增加db存在性校验
    if (!db) {
        return res.status(500).send('Database connection not ready');
    }

    var name = 'user' + Math.floor(Math.random()*10000);
    var email = name + '@mit.edu';

    var collection = db.collection('customers');
    var doc = {'name':name, 'email':email};
    // 替换弃用的insert为insertOne
    collection.insertOne(doc, function(err, result) {
        if (err) {
            console.error(err);
            return res.status(500).send('Failed to insert document');
        }
        console.dir(result);
        res.send(result);
    });      
});

app.get('/readMongo', function(req, res){  
    // 增加db存在性校验
    if (!db) {
        return res.status(500).send('Database connection not ready');
    }

    db.collection('customers')
      .find()
      .toArray(function(err, docs) {
          if (err) {
              console.error(err);
              return res.status(500).send('Failed to fetch documents');
          }
          console.dir(docs);
          res.send(docs);
    });
});

app.listen(3000);

关键修改点

  • 连接MongoDB时,从客户端对象client中通过client.db('dockerdemo')获取数据库实例,赋值给db变量。
  • 将collection.insert()替换为collection.insertOne(),适配新版驱动API。
  • 在/createMongo和/readMongo路由中增加db存在性校验,返回明确的错误信息,避免未连接时的崩溃。

内容的提问来源于stack exchange,提问作者Sar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:12:32