TypeError:db.collection 不是函数

Posted

技术标签:

【中文标题】TypeError:db.collection 不是函数【英文标题】:TypeError: db.collection is not a function 【发布时间】:2017-10-02 10:09:15 【问题描述】:

我正在尝试将数据发布到我在 mLab 上创建的数据库中,我收到此错误,但我不知道出了什么问题。我还阅读了之前关于此主题的问题,但我无法解决我的错误,因为我是新手。所以在这里我发布了我正在尝试实现的代码,它取自本教程https://medium.freecodecamp.com/building-a-simple-node-js-api-in-under-30-minutes-a07ea9e390d2。

server.js

const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const bodyParser = require('body-parser');

const db = require('./config/db');


const app = express();

const port = 8000;

app.use(bodyParser.urlencoded(extened:true));


MongoClient.connect(db.url,(err,database) =>

    if (err) return console.log(err)
    require('./app/routes')(app,);
    app.listen(port,() => 
        console.log("We are live on"+port); 
    );

)

db.js

module.exports = 
  url : "mongodb://JayTanna:Jay12345@ds147510.mlab.com:47510/testing"
;

index.js

const noteroutes = require('./note_routes');

module.exports = function(app,db)

    noteroutes(app,db);

;

note_routes.js

module.exports = function(app, db) 
  app.post('/notes', (req, res) => 
    const note =  text: req.body.body, title: req.body.title ;
    db.collection('notes').insert(note, (err, result) => 
      if (err)  
        res.send( 'error': 'An error has occurred' ); 
       else 
        res.send(result.ops[0]);
      
    );
  );
;

【问题讨论】:

在你的 index.js 中,我看不到你在哪里声明 db - 你需要吗? 如果你想学习 mongoDB,可以下载 NPM Mongo Models。 npmjs.com/package/mongo-models漂亮的node包,可以打开Mongo Models代码学习。 【参考方案1】:

在您的 server.js 中,您传递的是空对象,您需要将数据库作为第二个参数传递给您的 routes/index.js 导出函数所期望的。

PFB 更新 server.js :

const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const bodyParser = require('body-parser');

const db = require('./config/db');

const app = express();

const port = 8000;

app.use(bodyParser.urlencoded(extended:true));

MongoClient.connect(db.url,(err,database) =>

    if (err) return console.log(err)
    //require('./app/routes')(app,);
    //check below line changed
     require('./app/routes')(app, database);
    app.listen(port,() => 
        console.log("We are live on"+port); 
    );

);

【讨论】:

Req.body.body 和 req.body.title 都给我“未定义”,你觉得这有什么不对吗?? 需要添加app.use(bodyParser.json());中间件 标题来自post还是得到它是一个URL slug参数? 没有。当我执行 console.log(req.body) 时,它给了我标题和正文,但是当我执行 console.log(req.body.body) 时,它给了我 undefind。 只要确保我得到这个正确,当您执行 console.log(req.body) 时,您将获得属性标题和正文,然后您尝试记录 req.body.title 和 req .body.body。你能仔细检查一下这些是 req.body 的属性还是 req 的属性?【参考方案2】:

错误在 mongodb 库中。尝试安装mongodb 的版本2.2.33。删除您的node_modules 目录并添加

"dependencies": 
   "mongodb": "^2.2.33"

然后

npm install

你来了

【讨论】:

... 令人难以置信的是问题出在 mongodb 上的版本上。我的 package.json 默认通过 npm install mongodb --save 安装了 3.0.0-rc0 @ 很棒 @yaxartes @DavidAnderton 问题不在于 MongoDB,而只是语法问题。如果您不想降级 mongodb,请参阅下面的解决方案,希望对您有所帮助! @antikytheraton 降级不是最佳解决方案,需要正确的语法 @Ganesh 我同意你的看法。当mongo当时直接更新到版本3时,这个解决方案是我解决这个问题的方法【参考方案3】:
module.exports = function(app, db) 
  app.post('/notes', (req, res) => 
  const note =  text: req.body.body, title: req.body.title ;
  db.collection('notes').insert(note, (err, result) => 
...

db -> 客户端

module.exports = function(app, client) 
  var db = client.db("name");
  app.post('/notes', (req, res) => 
  const note =  text: req.body.body, title: req.body.title ;
  db.collection('notes').insert(note, (err, result) => 
...

【讨论】:

【参考方案4】:

所以我投票给了答案,说只是降级到 mongodb 2.2.33,因为我尝试过它并且它有效,但后来我对降级以解决问题感到很奇怪,所以我找到了允许你保留的解决方案版本 >= 3.0。如果有人发现此问题并且他们的问题没有像接受的答案那样传递空白参考,请尝试此解决方案。

当你跑步时..

MongoClient.connect(db.url,(err,database) => 

在 mongodb 版本 >= 3.0 中,database 变量实际上是您尝试使用 database.collection('whatever') 访问的对象的父对象。要访问正确的对象,您需要引用您的数据库名称,对我来说这是通过这样做

MongoClient.connect(db.url,(err,database) => 
  const myAwesomeDB = database.db('myDatabaseNameAsAString')
  myAwesomeDB.collection('theCollectionIwantToAccess')

这解决了我在运行我的 node.js 服务器时的错误,希望这可以帮助那些不想降级他们的版本的人。

(另外,如果您由于某种原因不知道您的数据库名称,只需执行一个 console.log(database),您就会将其视为对象属性)


编辑(2018 年 6 月):

根据this,回调实际上返回的是数据库连接的客户端,而不是数据库本身。

因此,要获取数据库实例,我们需要使用this method,它接受dbName。在文档中它说If not provided, use database name from connection string.,正如@divillysausages 在下面的cmets 中提到的那样。

简而言之,如果dbName由url提供,我们应该调用database.db().collection('theCollectionIwantToAccess');,其中database实际上是client以便更好地理解

【讨论】:

我尝试了同样的事情,但是在 database.db('dbname') 给出 db 对象之前调用了 db.collection 查询。从而得到相同的错误消息 虽然,database.db('dbname') 给出了正确的对象,但在此之前查询已经执行,给出了错误 here's V2 和 V3 之间的重大变化列表 我有点困惑 MongoDB 自己的文档甚至没有显示这一点。 仅供参考,如果您的连接字符串包含数据库名称(例如mongodb://localhost:27107/MyDB,那么它将被设置为返回的 MongoClient 上的默认值(在此示例中为database)。这让您可以调用database.db() 获取实际数据库【参考方案5】:

卸载现有的 mongodb 包并使用以下命令重新安装解决了我的问题。 :)

npm uninstall mongodb --save

npm install mongodb@2.2.33 --save

PS:感谢@MihirBhende 和@yaxartes

仅供参考,

如果您是该领域的新手,请首选来自 https://github.com/mongodb/node-mongodb-native/releases 的非 rc 版本。

【讨论】:

【参考方案6】:
MongoClient.connect(uristring, function (err, database) 
      var db=database.db('chatroomApp');
      var collections=db.collection('chats');
);

在尝试访问集合之前需要先获取数据库。

【讨论】:

【参考方案7】:

在你的 package.json 中。

确保以下版本如下所示:

"nodemon": "^1.12.1"
"mongodb": "^2.2.33"

以上 nodemon 和 mongodb 版本一起工作没有任何错误。 所以你的 package.json 应该是这样的:

    
  "name": "myapi",
  "version": "1.0.0",
  "description": "Json Api",
  "main": "server.js",
  "scripts": 
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon server.js"
  ,
  "author": "Riley Manda",
  "license": "ISC",
  "dependencies": 
    "body-parser": "^1.18.2",
    "express": "^4.16.2",
    "mongodb": "^2.2.33"
  ,
  "devDependencies": 
    "nodemon": "^1.12.1"
  

别忘了在降级后运行 npm install

【讨论】:

【参考方案8】:

根据mongo文档,我们需要如下改变连接,

The legacy operation
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => 
    // Database returned
);

is replaced with
MongoClient.connect('mongodb://localhost:27017/test', (err, client) => 
    // Client returned
    var db = client.db('test');
);

不需要降级mongo版本:)

【讨论】:

所以我传递的网址有多深,它只会给我一个客户。不是吗?【参考方案9】:

我也遇到了这个问题,我正在关注演示者将集合用作函数的教程。它从来没有为我工作过。我发现演示者使用的是 2.3.4 版本的 mongodb npm 模块。该模块现已进入 3.x.x 版。当我更改 package.json 文件以请求 mogodb npm 模块的 2.x.x 版本时,突然一切正常。

我认为发生的事情是模块被更改以将集合更改为不同的对象。不知道如何使用新版本,但如果你指定你想要 2.x.x 版本,旧的方式应该可以工作。具体来说,我可以确认(来自我的 package.json 文件,“依赖项”部分)“mongodb”:“^2.2.31”有效。

最好的方法:

$> npm install mongodb@2.2.31 --save

【讨论】:

【参考方案10】:

我遇到了同样的问题。自创建视频以来,节点的 mongodb 驱动程序模块似乎已更新。我在有效的文档中找到了下面的代码。

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

var url = 'mongodb://localhost:27017/<dbName>';
MongoClient.connect(url, (err, db) => 
   db.collection('<collection-name>').find().toArray(function(err, docs) 

    // Print the documents returned
    docs.forEach(function(doc) 
        console.log(doc);
    );

    // Close the DB
    db.close();
    );

);  

替换为

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

  var url = 'mongodb://localhost:27017'; // remove the db name.
    MongoClient.connect(url, (err, client) => 
       var db = client.db(dbName);
       db.collection('<collection-name>').find().toArray(function(err, docs) 

        // Print the documents returned
        docs.forEach(function(doc) 
            console.log(doc);
        );

        // Close the DB
        client.close();
        );

    );  

这是最新文档的link,以防我们遇到更多语法问题。

【讨论】:

【参考方案11】:

工作代码使用:

npm version 6.0.1,
Node version 10.1.0
"body-parser": "^1.18.3",
"express": "^4.16.3",
"mongodb": "^3.1.0-beta4"
"nodemon": "^1.17.4"

这里是server.js代码:

const express       = require('express');
const MongoClient   = require('mongodb').MongoClient;
const bodyParser    = require('body-parser');
const db            = require('./config/db');
const app           = express();
const port          = 8000;

app.use(bodyParser.urlencoded( extended:true ))
MongoClient.connect(db.url,  useNewUrlParser: true ,  (err, client)=>
    var db = client.db('notable');
    if (err) return console.log(err)

    require('./app/routes')(app, client);
    app.listen(port,()=>
        console.log('we are live at '+ port);
    );
)

这里是config/db.js代码:

module.exports = 
    url:"mongodb://127.0.0.1:27017"

这里是routes/note_routes.js

 var ObjectId = require('mongodb').ObjectID;
 module.exports= function (app, client) 
        var db = client.db('notable');
        //find One
        app.get('/notes/:id', (req, res)=>
                const id =req.params.id;
                const details ='_id': new ObjectId(id)
                db.collection('notes').findOne(details, (err, item)=>
                    if(err)
                    
                        res.send('error':"An error has occured")
                    
                    else
                    
                        res.send(item)
                    
                );
            );
            //update rout
            app.put('/notes/:id', (req, res)=>
                const id =req.params.id;
                const details ='_id': new ObjectId(id)
                const note =text: req.body.body, title: req.body.title;
                db.collection('notes').update(details, note, (err, item)=>
                    if(err)
                    
                        res.send('error':"An error has occured")
                    
                    else
                    
                        res.send(item)
                    
                );
            );

            //delete route
            app.delete('/notes/:id', (req, res)=>
                const id =req.params.id;
                const details ='_id': new ObjectId(id)
                db.collection('notes').remove(details, (err, item)=>
                    if(err)
                    
                        res.send('error':"An error has occured")
                    
                    else
                    
                        res.send("Note "+id+"deleted!")
                    
                );
            );
            //insert route
            app.post('/notes', (req, res)=>
                const note =text: req.body.body, title: req.body.title;
                db.collection('notes').insert(note, (err, results)=>
                    if(err)
                    
                        res.send('error':"An error has occured")
                    
                    else
                    
                        res.send(results.ops[0])
                    
                );

            );
        ;

【讨论】:

【参考方案12】:

非常感谢 Dilum Darshana!你的建议很有帮助。我只想补充一点,如果你使用 Promise,它看起来像这样:

let db;
MongoClient.connect('mongodb://localhost/collectionName').then(connection => 
    db = connection.db('collectionName');
    app.listen(3000, () => 
        console.log("App started on port 3000");
    ); 
).catch(error => 
    console.log('ERROR:', error);
);

【讨论】:

网址是否应该包含集合名称?我正在查看mongodb.github.io/node-mongodb-native/driver-articles/…,除非您的数据库和集合被命名为相同的东西,否则 url 格式似乎不支持? 我认为是的,因为你需要为你的目标获取某个对象,而某个对象无论如何都是某个集合的一部分,它是数据库的一部分。当然,如果我正确理解了您的问题。【参考方案13】:

对于我使用的最新版本"mongodb": "^3.1.3" 下面的代码解决了我的问题

server.js

MongoCLient.connect(db.url,(err,client)=>
    var db=client.db('notable123');
    if(err)
    return console.log(err);
    
    require('./server-app/routes')(app,db);
    app.listen(port, ()=> 
        console.log("we are live on : "+ port);
    )

)

你的邮政编码就像

module.exports = function(app,db) 
    app.post('/notes',(req,res)=>
        const note= text: req.body.body,title:req.body.title;
        db.collection('notes').insertOne(note,(err,result)=>
            if(err) 
                res.send("error":"Ann error has occured"); 
             else 
                res.send(result.ops[0])
            
        );
    );
;

【讨论】:

【参考方案14】:

不要在连接 url 中使用数据库名称:

const mongo_url = 'mongodb://localhost:27017'

改用下面的方法:

MongoClient.connect(mongo_url ,  useNewUrlParser: true , (err, client) => 
        if (err) return console.log(err)
        const  db =  client.db('student')
        const collection = db.collection('test_student');
        console.log(req.body);
        collection.insertOne(req.body,(err,result)=>
            if(err)
                res.json(err);
            
            res.json(result);
        );
    );

【讨论】:

请在答案中添加更多内容,解释为什么 OP 应该使用您的代码以及它如何解决他们的问题!【参考方案15】:
const MongoClient = require('mongodb').MongoClient;

//connection url

 const url = 'mongodb://localhost:27017/myproject';

 MongoClient.connect(url,useNewUrlParser: true,(err,client)=> 
  if(err) 
    return console.dir(err)
  

   console.log('Connected to MongoDB')

  //get the collection
  let db = client.db('myproject');
  db.collection('users').insertOne(
  name: 'Hello World',
  email: 'helloworld@test.com'

  ,(err,result)=> 
  if(err) 
      return console.dir(err)
  
  console.log("Inserted Document");
  console.log(result);

     );
   );

【讨论】:

【参考方案16】:

我有一个简单的解决方案:

note_routes.js

db.collection('notes').insert(note, (err, result) => 

替换

db.db().collection('notes').insert(note, (err, result) => 

【讨论】:

【参考方案17】:

我正在做同样的教程有同样的问题。我刚刚检查了所有答案并找到了适合我的答案。

MongoClient.connect(db.url,  useUnifiedTopology: true , (err, client) => 
var database = client.db('test');
if (err) return console.log(err) 
require('./app/routes')(app, database);
app.listen(port, () =>  console.log('We are live on ' + port);); )

将数据库更改为客户端并将数据库定义为 client.db('test')

【讨论】:

【参考方案18】:
MongoClient.connect(db.url,(err,database) =>
    if (err) return console.log(err)
    //require('./app/routes')(app,);
    //try this 
     require('./app/routes')(app,database);
    app.listen(port,() => 
        console.log("We are live on"+port); 
    );
)

这里您必须将数据库包含在空的 中。

您也可以尝试将 mongodb 安装到最新版本,这将解决问题。

npm install mongodb@2.2.33 --save 

else npm install 在节点模块中添加“mongodb”的依赖:“^2.2.33”。

【讨论】:

以上是关于TypeError:db.collection 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

db.collection(collection_name).drop() 不工作。创建的数据库没有被删除

db.collection.insertMAny 不工作,我的代码有问题吗?

如何在不再次调用 db.collection 的情况下获取文档和编辑数据?

mongodb ? db.collection.find() ???????

MongoDB笔记

Python + MongoDB,如何动态选择DB Collection