猫鼬模式尚未注册模型


80

我正在学习平均堆栈,当我尝试使用启动服务器时

npm start

我得到一个例外,说:

schema hasn't been registered for model 'Post'. Use mongoose.model(name, schema)

这是我在/models/Posts.js中的代码

var mongoose = require('mongoose');

var PostSchema = new mongoose.Schema({
    title: String,
    link: String, 
    upvotes: { type: Number, default: 0 },
    comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});

mongoose.model('Post', PostSchema);

如我所见,模式应该为模型“ Post”注册,但是什么可能导致异常抛出呢?

提前致谢。

编辑:这是异常错误

/home/arash/Documents/projects/personal/flapper-news/node_modules/mongoose/lib/index.js:323
  throw new mongoose.Error.MissingSchemaError(name);
        ^
MissingSchemaError: Schema hasn't been registered for model "Post".
Use mongoose.model(name, schema)

这是带有猫鼬初始化的app.js代码:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');

前行:

app.use('/', routes);

您在其他地方犯了一个错误。上面的代码是有效的。也许您在Post.js某个地方“需要” ,但是您从未“导出”模型。
尼尔·卢恩

@NeilLunn好的,我将编辑带有异常错误的问题,因为这就是我可以阅读的全部内容。也许其他人可以看到我看不到的东西
惊叹于2014年

嗯 您是否曾经在“需要”的地方“出口”过?我认为这是这里缺少的代码。
尼尔·卢恩

@NeilLunn您的意思是在app.js中?让我也放上app.js代码(仅用于猫鼬部分)
Arash moeen 2014年

如果该ID是您的代码,则您永远不会“导出”模型。盖茨现在三遍了。您现在应该得到这个。
尼尔·卢恩

Answers:


142

模型导出不是问题。我遇到过同样的问题。

真正的问题是需要模型声明

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');

低于路线依赖关系。只需将mongoDB依赖关系移到路由依赖关系之上即可。它应该是这样的:

// MongoDB
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

@Mark评论var mongoose = require(“ mongoose”); 和评论和帖子类似,然后添加var Posts = require(“ Posts”); 直接在router.get和router.post内部,以及类似的注释
Dhyey '16

这似乎解决了Schema错误,但现在出现了“未定义路由器”错误routes/index.js。我了解缺少的参考错误是什么,但是我认为这不需要实例化。
gin93r

@maiamachine您曾经获得过Thinkster教程吗?我已经研究了大约一个星期,并且到处都是随机问题。您是否有可能在jsFiddle上发布工作代码或其他东西?
Travis Heeter '17

@ user8264:如何为动态创建的架构模型实现您的概念?
Pappa S

46

如果有人不能通过正确答案的方法来解决它(例如我),请尝试研究模式的创建。我将“ ref”写为“ User”,但正确的是“ user”。

错误:

createdBy: {
    type: Schema.Types.ObjectId,
    ref: 'User'
}

正确:

createdBy: {
    type: Schema.Types.ObjectId,
    ref: 'user'
}

2
解决了我的问题:)
中旬

30

如果您使用多个mongoDB连接


注意,使用.populate()时,您必须提供模型,因为猫鼬只会在同一连接上“查找”模型。即在哪里:

var db1 = mongoose.createConnection('mongodb://localhost:27017/gh3639');
var db2 = mongoose.createConnection('mongodb://localhost:27017/gh3639_2');
var userSchema = mongoose.Schema({
  "name": String,
  "email": String
});

var customerSchema = mongoose.Schema({
  "name" : { type: String },
  "email" : [ String ],
  "created_by" : { type: mongoose.Schema.Types.ObjectId, ref: 'users' },
});

var User = db1.model('users', userSchema);
var Customer = db2.model('customers', customerSchema);

正确:

Customer.findOne({}).populate('created_by', 'name email', User)

要么

Customer.findOne({}).populate({ path: 'created_by', model: User })

错误(产生“模式尚未注册模式”错误):

Customer.findOne({}).populate('created_by');

2
此解决方案解决了我的问题!findOne({}).populate({ path: 'created_by', model: User })
里卡多·席尔瓦

为我做了。感谢芽
Aleks

@ user3616725:如何为动态创建的架构模型实现您的概念?
Pappa S

1
@PappaS,只要您知道模型名称,就可以输入模型名称,而不是模型实例:Customer.findOne({}).populate({ path: 'created_by', model: 'User' })但是,模型必须已经在同一猫鼬实例上注册。
user3616725

11

我使用以下方法解决了问题

const mongoose = require('mongoose');
const Comment = require('./comment');

const PostSchema = new mongoose.Schema({
            title: String,
            link: String, 
            upvotes: { type: Number, default: 0 },
            comments: [{ type: mongoose.Schema.Types.ObjectId, ref: Comment }]
        });
mongoose.model('Post', PostSchema);

请注意,这里ref没有string类型值,现在它是指Comment架构。


1
尝试了很多,这确实是我的唯一方法-在尝试了数十种变体之后-使它轻松工作。
Stefan Walther

如何为动态创建的架构模型实现您的概念?
Pappa S

4

当我们在猫鼬模型之间创建错误的引用(ref)时,也会弹出此错误。

就我而言,我指的是文件名而不是型号名。

例如:

const userModel = mongoose.model("user", userSchema);

我们应该引用“用户”(型号名称)而不是“用户”(文件名称);


当一个模型引用另一个猫鼬模型时,我遇到了同样的问题。受您的答案启发,请更改为我当前的MongoDB集合所引用的正确的MongoDB集合名称。问题解决了。非常感谢你。
GoodApple

2
.\nodeapp\node_modules\mongoose\lib\index.js:452
      throw new mongoose.Error.MissingSchemaError(name);
      ^
MissingSchemaError: Schema hasn't been registered for model "users".
Use mongoose.model(name, schema)
    at new MissingSchemaError

在server.js上使用setTimeout时,此错误已解决

mongoose.connect(env.get('mongodb.uri'), { useNewUrlParser: true })
  .then(() => logger.info("MongoDB successfully connected"))
  .catch(err => logger.error(err));
app.use(passport.initialize());
setTimeout(function() {
  require("./src/utils/passport")(passport);
}, 3000);

2

这是https://mongoosejs.com/docs/populate.html#cross-db-populate

它说我们必须将模型作为第三个参数传递。

例如

//Require User Model
const UserModel = require('./../models/User');
//Require Post Model
const PostModel = require('./../models/Post');
const posts = await PostModel.find({})
            .select('-__v')
            .populate({
              path: 'user',
              select: 'name -_id',
              model: UserModel
            });
//or 
const posts = await PostModel.find({})
            .select('-__v')
            .populate('user','name', UserModel);


1

我也面临着同样的问题。解决我的问题的方法是查看与实际导出的模型相比具有不同名称的ref参数,因此未找到此类模型。

userSchema.virtual('tasks', {
    ref: 'Task',
    localField: '_id',
    foreignField: 'owner'
})
  

而我实际出口的是:

const Tasks = mongoose.model('Tasks', taskSchema)

module.exports = Tasks

纠正问题后TaskTasks我的问题已解决


0

详细阐述以上Rafael Grilli的答案,

正确:

var HouseSchema = new mongoose.Schema({
  date: {type: Date, default:Date.now},
  floorplan: String,
  name:String,
  house_id:String,
  addressLine1:String,
  addressLine2:String,
  city:String,
  postCode:String,
  _locks:[{type: Schema.Types.ObjectId, ref: 'xxx'}] //ref here refers to the first parameter passed into mongoose.model()
});
var House = mongoose.model('xxx', HouseSchema, 'houseschemas');

0

您还应该检查数据库中没有脏数据。我最终得到了一个包含引用模型的小写版本的文档(user而不是User)。这会导致错误,并且难以追踪。

易于修复的快速mongo查询:

db.model.updateMany({ approvedByKind: 'user' }, { $set: { approvedByKind: 'User' } })

0

就我而言,这个问题是因为我没有在应用程序中包括模型或ref模型。所以,你应该需要Post modelComment model您的节点应用。


0

创建新模型时,请使用与模型名称相同的名称。

例如:如果我有猫鼬模型,例如:

var Post = mongoose.model("post",postSchema);

然后,我必须通过写作来引用帖子集ref:"post"


0

我也面临同样的问题,但是我通过删除module.exports解决了

module.exports = mongoose.model('user',userSchema); //删除module.exports并使用如下代码: mongoose.model
('user',userSchema);

const mongoose = require('mongoose');
const ObjectId = require('mongoose').ObjectId;

var userSchema = new mongoose.Schema({
    Password: { type: String },  
    Email: { type: String, required: 'This field is required.', unique:true },  
    songs: [{ type: ObjectId, ref: 'Songs'}]
});

// Custom validation for email
userSchema.path('Email').validate((val) => {
    emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return emailRegex.test(val);
}, 'Invalid e-mail.');

// module.exports = mongoose.model('user', userSchema);  // remove 'module.exports ='
mongoose.model('user', userSchema); // resolved issue

0

问题出在引用上,始终确保将引用引用到您要从模型中导出的任何名称。

//型号

const Task = mongoose.model('**Tasks**', taskSchema);

//引用

userSchema.virtual('tasks', {
ref: '**Tasks**',
localField: '_id', // field in current model
foreignField: 'owner' // corresponding field in other model

});


0

我的问题是使用下面的方法

adminModel.findById(req.params.id).populate({路径:“用户”,模型:userModel //用户集合名称})


0

只是想为我补充一点,我在导入架构时使用了结构化,这会导致其失败。

正确

var intakeSchema = require('../config/models/intake')

不正确的

var { intakeSchema } = require('../config/models/intake')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.