Mongoose Schema 尚未注册模型

Posted

技术标签:

【中文标题】Mongoose Schema 尚未注册模型【英文标题】:Mongoose Schema hasn't been registered for model 【发布时间】:2015-01-05 05:42:50 【问题描述】:

我正在学习平均堆栈,当我尝试使用

启动服务器时
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)

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

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

行前:

app.use('/', routes);

【问题讨论】:

你在别处犯了错误。上面的代码是有效的。也许您在某处“需要”(ing)Post.js,但您从未“导出”模型。 @NeilLunn 好的,我将用我的异常错误编辑问题,因为这就是我可以从中读取的全部内容。也许别人能看到我看不到的东西 @Umm。你有没有在以后“需要”的地方“出口”?我认为这是这里缺少的代码。 @NeilLunn 你的意思是在 app.js 中?让我也放 app.js 代码(仅限猫鼬部分) 如果那是你的代码,那么你永远不会“导出”模型。哎呀现在三遍。你现在应该得到这个了。 【参考方案1】:

如果您使用多个 mongoDB 连接


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

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 )

// you can pass the model NAME instead of model instance
Customer.findOne().populate( path: 'created_by', model: 'User' ) 

不正确(产生“尚未为模型注册模式”错误):

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

【讨论】:

这个解决方案解决了我的问题! findOne().populate( path: 'created_by', model: User ) 为我做的。谢谢芽 @user3616725:如何实现您的动态创建模式模型的概念? @PappaS 只要您知道模型名称,您就可以传递模型名称,而不是模型实例:Customer.findOne().populate( path: 'created_by', model: 'User' ) 但模型必须已经在同一个猫鼬实例上注册。 这对我有用。非常感谢您的回答【参考方案2】:

当您使用的模型依赖于另一个模型,但该模型尚未注册时,就会出现此问题。

一个简单的解决方法是 将model 添加到popualte 而不是依赖架构中的ref

=>> 示例

const jobs = await Job.find().populate(
    path: "jobDescriptions",
    model: JobDesc,
    select: "list",
    populate: 
      path: "list",
      select:"name list",
      model: Skill,
    ,
  );

【讨论】:

【参考方案3】:

你没有给模型任何价值

在我的例子中,我使用的模型在建立 MongoDB 连接时没有更新。

所以,我有类似的东西

const Device = require('../../models/device')
// make use of Device

有了这个连接

conn = await mongo.createConnection(conn,
      [JobApplication, Job, User])

修复

你必须在启动连接时将模型添加到conn

conn = await mongo.createConnection(conn,
      [JobApplication, Job, User, Device])

请注意,我在连接中添加了Device

【讨论】:

【参考方案4】:

只是想补充一点,我在导入导致它失败的架构时使用了解构。

正确

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

不正确

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

【讨论】:

【参考方案5】:

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

在我的例子中,我指的是文件名而不是模型名。

例如:

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

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

【讨论】:

当一个模型引用另一个猫鼬模型时,我遇到了同样的问题。受您的回答启发,更改为我当前 MongoDB 集合所指的正确 MongoDB 集合名称。问题解决了。非常感谢。【参考方案6】:

我也遇到了同样的问题。 我的问题的解决方案是查看与我实际导出的模型相比名称不同的 ref 参数,因此没有找到这样的模型。

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

而我实际导出的是:-

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

module.exports = Tasks

Task改成Tasks后,我的问题就解决了

【讨论】:

【参考方案7】:

我的问题是用下面的方法解决的

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

【讨论】:

【参考方案8】:

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

// 型号

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

//参考文献

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

);

【讨论】:

【参考方案9】:

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

解决了

module.exports = mongoose.model('user', userSchema); // 移除 module.exports 并使用 like:: 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

【讨论】:

【参考方案10】:

这里是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);

【讨论】:

这对我有用。我正在使用来自两个不同来源的模型;一些模型来自自定义库,还有一些来自我的本地项目。【参考方案11】:

在创建新模型时引用您在模型名称中引用的相同名称。

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

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

那我得写ref:"post"参考贴子集合了。

【讨论】:

【参考方案12】:

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

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 架构。

【讨论】:

非常感谢,这对我来说确实是唯一的方法——在尝试了几十种变体之后——让它轻松工作。 如何实现你的动态创建模式模型的概念?【参考方案13】:
.\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);

【讨论】:

【参考方案14】:

就我而言,这个问题是因为我没有将模型或参考模型包含到应用程序中。 所以你应该在你的节点应用程序中要求Post modelComment model

【讨论】:

【参考方案15】:

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

通过快速 mongo 查询轻松修复:

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

【讨论】:

【参考方案16】:

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

真正的问题是模型的 require 语句

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 中,对于 Comments 也是如此 这似乎解决了 Schema 错误,但现在routes/index.js 中出现“未定义路由器”错误。我知道缺少引用错误是什么,但我认为这不需要实例化..有人知道吗? @maiamachine 你有没有让 Thinkster 教程工作?我已经研究了大约一个星期,并且到处都是随机问题。您有机会在jsFiddle 或其他地方发布工作代码吗? @user8264:如何实现您的动态创建模式模型的概念?【参考方案17】:

详细阐述上面 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');

【讨论】:

【参考方案18】:

如果有人无法用正确答案的方法解决它(比如我),请尝试查看架构的创建。我将 'ref' 写为 'User',但正确的是 'user'。

错误:

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

正确:

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

【讨论】:

解决了我的问题 :)

以上是关于Mongoose Schema 尚未注册模型的主要内容,如果未能解决你的问题,请参考以下文章

模式尚未注册模型错误显示

MissingSchemaError:尚未为模型“用户”注册架构

在 Node JS 中填充 Mongoose

NodeJS + Mongoose:MissingSchemaError:模式尚未注册模型“类别”

mongoose 模式未在填充字段中注册错误

Mongoose Schema hasn't been registered for model