Node.js中MongoDB 3.6获取Collection报错:get(...).getCollection不是函数
解决MongoDB 3.6 + Node.js中无法获取Collection的TypeError问题
你碰到的问题其实是MongoDB Node.js驱动3.x版本的API变更导致的——在3.x及以后的驱动版本里,MongoClient.connect的回调函数返回的不再是直接的数据库(DB)对象,而是MongoClient实例,这就是为什么你打印state.db看到的是MongoClient,调用getCollection会抛出TypeError: get(...).getCollection is not a function的原因。
问题根源详解
在旧版驱动(比如2.x)中,MongoClient.connect的第二个回调参数直接就是目标DB对象;但从3.x开始,这个参数变成了MongoClient客户端实例,你需要通过它的db()方法来获取对应的数据库对象:
- 如果你的连接字符串
DATABASE_URL已经包含了数据库名称(比如mongodb://localhost:27017/BotDb),直接调用client.db()就能拿到该数据库实例 - 如果连接字符串没有指定数据库,需要传入数据库名称,比如
client.db('BotDb')
而Mongo控制台里的db.getCollection("users")能正常工作,是因为控制台环境里的db变量本身就是当前选中的数据库实例,和Node.js驱动的API逻辑不一样,别搞混了。
修改后的代码示例
1. 修正数据库连接函数
var moment = require('moment'); var MongoClient = require('mongodb').MongoClient; var state = { db: null, } function get() { return state.db; } exports.connect_database = function(done) { if (state.db) return done() // 把回调参数名改为client,避免和DB对象混淆 MongoClient.connect(process.env.DATABASE_URL, function(err, client) { if (err) return done(err) // 这里根据你的连接字符串情况选择: // 情况1:连接字符串已包含数据库名 state.db = client.db() // 情况2:连接字符串未指定数据库,手动传入名称 // state.db = client.db('BotDb') done() }) }
2. 修正Collection获取逻辑
另外,MongoDB驱动推荐用collection()方法(getCollection()的别名)来获取集合,代码可以调整得更符合新API习惯:
exports.return_collection = function(collection_name, callback) { var result_array = []; // 改用collection()方法 var collection = get().collection(collection_name); var result = collection.find() result.forEach(function(res) { result_array.push(res); }, function(error) { console.log("error: ") console.log(error); if (!error) callback(result_array); }); }
这样修改后,state.db就会是正确的DB对象,调用collection()(或getCollection())就能正常获取集合了。
内容的提问来源于stack exchange,提问作者ste
相关产品推荐
相关产品推荐

