【问题标题】:TypeError: Object {...} has no method 'find' - when using mongoose with expressTypeError: Object {...} has no method 'find' - 当使用 mongoose 和 express
【发布时间】:2014-08-02 01:41:13
【问题描述】:

我在使用带有 express 的 mongoose 模式从 MongoDB 获取数据时遇到问题。 我首先在一个文件(mongoosetest.js)中只用猫鼬进行了测试,它工作正常。但是当我开始用快速路由和配置文件来划分它时,事情就开始崩溃了。我确信这很简单,但我在过去的 3 个小时里都在谷歌上搜索并试图找出我做错了什么,但找不到任何与我的流程匹配的内容足以进行比较。

mongoosetest.js(这很好用,但不适用于我的应用程序)

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/meanstack');

var db = mongoose.connection;

var userSchema = mongoose.Schema({
  name: String
}, {collection: 'users'});

var User = mongoose.model('User', userSchema);

User.find(function(err, users) {
  console.log(users);
});

这些文件是我遇到问题的地方。我确信这很愚蠢,可能是使用外部文件、导出和要求的直接结果。我的 server.js 文件刚刚启动并配置 express。我还有一个路由文件和一个 db 配置文件。

路由文件(allRoutes.js)

var express = require('express');
var router = express.Router();
var db = require('../config/db');
var User = db.User();

// routes
router.get('/user/list', function(req, res) {
  User.find(function(err, users) {
    console.log(users);
  });
});

// catch-all route
router.get('*', function(req, res) {
  res.sendfile('./public/index.html');
});

module.exports = router;

dbconfig 文件 (db.js)

var mongoose = require('mongoose');
var dbHost = 'localhost';
var dbName = 'meanstack';
var db = mongoose.createConnection(dbHost, dbName);
var Schema = mongoose.Schema, ObjectId = Schema.ObjectId;

db.once('open', function callback() {
  console.log('connected');
});

// schemas
var User = new Schema({
  name    : String
}, {collection: 'users'});

// models
mongoose.model('User', User);
var User = mongoose.model('User');

//exports
module.exports.User = User;

当我浏览到 localhost:3000/user/list 时收到以下错误

TypeError: Object { _id: 5398bed35473f98c494168a3 } has no method 'find' at 
Object.module.exports [as handle] (C:\...\routes\allRoutes.js:8:8) at next_layer 
(C:\...\node_modules\express\lib\router\route.js:103:13) at Route.dispatch 
(C:\...\node_modules\express\lib\router\route.js:107:5) at 
C:\...\node_modules\express\lib\router\index.js:213:24 at Function.proto.process_params 
(C:\...\node_modules\express\lib\router\index.js:284:12) at next 
(C:\...\node_modules\express\lib\router\index.js:207:19) at Function.proto.handle 
(C:\...\node_modules\express\lib\router\index.js:154:3) at Layer.router 
(C:\...\node_modules\express\lib\router\index.js:24:12) at trim_prefix 
(C:\...\node_modules\express\lib\router\index.js:255:15) at 
C:\...\node_modules\express\lib\router\index.js:216:9

就像我说的那样,由于我的单个文件 (mongoosetest.js) 可以按预期工作,因此我试图组织我的代码可能很愚蠢。谢谢。

【问题讨论】:

    标签: node.js express mongoose


    【解决方案1】:

    我想通了。

    显然,db.once('open'... 与 mongoose.connect 不同。将我的 dbconfig.js 文件切换到以下文件,一切都很好(使用 var User = db.User; 在 allRoutes. js 正如 Aaron Dufour 建议的那样)。

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema, ObjectId = Schema.ObjectId;
    
    mongoose.connect('mongodb://localhost/meanstack');
    
    // schemas
    var User = new Schema({
      name    : String
    }, {collection: 'users'});
    
    // models
    mongoose.model('User', User);
    
    //exports
    module.exports.User = mongoose.model('User');
    

    编辑:2 天内无法将此标记为答案。

    【讨论】:

    • 不是db.once vs mongoose.connect,而是mongoose.createConnection vs mongoose.connect。如果您需要打开多个连接,您应该只需要使用mongoose.createConnection。当您使用mongoose.createConnection 时,它将创建多个,您必须指定在查询调用中使用哪个。因为您没有指定要使用哪一个,所以查询挂起。切换到mongoose.connect只有一个连接,所以查询成功。
    • 有关更多信息,请参阅mongoosejs.com/docs/connections.html(或此堆栈溢出答案也很有用:stackoverflow.com/a/22838614
    • @dylants 谢谢,这对我帮助很大。我将原始代码更改为 db.model 而不是 mongoose.model 并且效果也很好。现在对我来说更有意义了。 mongoose.connection 为 mongoose 打开一个默认连接,但 mongoose.createConnection 打开并返回一个连接。我似乎一直在做的是创建/打开一个新连接,但试图摆脱我从未连接过的默认连接。
    • 对,完全正确:) 我不知道为什么 mongoose 在您调用 createConnection 时不使用默认连接 (connections[0]),如果它尚未建立/创建。相反,他们似乎希望您先使用connect,然后再使用createConnection 进行其他连接。
    【解决方案2】:

    你为什么打电话给User

    var User = db.User();
    

    试试

    var User = db.User;
    

    允许调用它,因为它是一个构造函数,但它可能不会返回任何有用的东西(错误消息暗示它正在构造一个空的 User 对象,我认为)。

    【讨论】:

    • var User = db.User;导致长时间挂起和超时。 db.User();导致即时错误。
    • @sdouble 但是在“长时间挂起”期间是console.loging 吗?您永远不会发送响应,因此挂起是预期的行为。
    • 不,什么都没有。我还在 c.log(users) 之前添加了另一个 console.log('test') 并且也没有回显。一旦它点击 .find,它就是吐司。如果我在一个文件中完成所有操作,我完全没有问题,所以我认为这与我引用的方式有关。
    猜你喜欢
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多