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

Posted

技术标签:

【中文标题】MissingSchemaError:尚未为模型“用户”注册架构【英文标题】:MissingSchemaError: Schema hasn't been registered for model "User" 【发布时间】:2014-01-16 21:37:30 【问题描述】:

在我的models/user.js 文件中:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var userSchema = new Schema(
    (define schema)
);
...
(save user)
...
(check password)
...
mongoose.model('User', userSchema);

在我的router/index.js 中,我有:

var mongoose = require('mongoose');
var User = mongoose.model('User');

引发错误:

MissingSchemaError: Schema hasn't been registered for model "User".

但是,如果在user.js 中,我会这样做(在最后一行)

module.exports = mongoose.model('User', userSchema);

index.js 我做var User = require('../models/User');,然后一切正常。

但它不应该,因为在config/pass.js 我正在做var User = mongoose.model('User'); 并且它完美地工作。

require('../models/User'); 语法在 Ubuntu 上不起作用,但在我的 Mac 上。

我该怎么办?我如何解决它?我查看了大量示例应用程序,包括 MEAN,但没有任何帮助。

【问题讨论】:

我遇到了类似的问题,虽然@verybadalloc 的回答很有帮助,但我想看看我是否可以用另一种方式解决它。然后,当我撤消更改时,它仍然有效。所以,现在我仍然很困惑,但你的问题和答案有所帮助。我尝试将导出更改为也导出架构,这似乎有所帮助,但现在我不完全确定什么有效,因为撤消更改似乎没有任何影响。 【参考方案1】:

我在尝试 MEAN 教程时遇到了同样的问题。

经过一番研究,我发现在 app.js 中,如果我将 require("./models/User") 放在 var routes = require("./routes/index") 之前,那么它可以工作。

像这样:


mongoose.connect("mongodb://localhost/news");
require("./models/Posts");
require("./models/Comments");

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

var app = express();

希望答案会有所帮助!

【讨论】:

好人,做同样的教程,这个答案为我节省了很多时间 确实有助于在路线之前添加模型 异步行为很强大,但正确使用也有点困难。感谢您的回答!【参考方案2】:

发生错误是因为在加载 router/index.js 时尚未解释 models/user.js。解决此问题的一种方法是执行以下操作:

var mongoose = require('mongoose');
//Load all your models
var User = require('./../models/user.js');

//Now, this call won't fail because User has been added as a schema.
mongoose.model('User');

然而,事实证明这违反了最佳实践,这表明所有这些配置内容都应该发生在您的 app.js 文件的开头。从madhums' example project看这个例子

var models_path = __dirname + '/app/models'
fs.readdirSync(models_path).forEach(function (file) 
  if (~file.indexOf('.js')) require(models_path + '/' + file)
)

请注意,他是在设置应用程序的路由器之前加载他的模型。 至于 Ubuntu 与 Mac 的问题,我相信这是因为 Ubuntu 中的相对路径必须以 ./ 开头。您只需将其更改为 ./../models/user.js,它适用于 Mac。

【讨论】:

该代码应该放在哪里?令我惊讶的是,删除 ./ 在两个系统中都有效,但 ./ 在 Ubuntu 上无效。 在您配置/启动快速服务器的文件中 - 在您的路线文件加载之前。【参考方案3】:

猫鼬模式 js 文件中的所有代码都应该在用于其他文件之前运行。

例如,以下代码 sn-p 确保执行 mongoose 架构文件/模块。

fs.readdirSync(__dirname + '/app/models').forEach(function (file) if (~file.indexOf('.js')) require(__dirname + '/app/models/' + file); );

或者架构文件可以通过调用手动执行

var User = require('./app/models/user.js')

在模型用于应用程序中的任何位置之前。

完成上述操作后,可以要求/执行其他使用猫鼬模型的模块。

【讨论】:

【参考方案4】:

我确实研究了很多,我找到了一个解决方案,所以我把这个解决方案分享给你,没有人可以面对我犯的那个小错误。

请记住,您只需在 ref 中添加与您在 model 中提供的名称相同的名称,因为它区分大小写( Product !== product )。

const Product = new mongoose.model('Product', productSchema);

product: 
    type: mongoose.Schema.ObjectId,
    ref: 'Product', <-- Should be same as modelName
    required: [true, 'Cart must belong to a product']

【讨论】:

【参考方案5】:

在加载模型文件加载之前尝试获取模型时出现此问题

我在 mean.io 项目中解决了同样的问题

在控制器中:

'use strict';
require('../models/settingsModel'); // load settingsModel.js file before get mongoose.model('Settings')
var mongoose = require('mongoose'),
    Settings = mongoose.model('Settings'),
    Q = require('q');

【讨论】:

【参考方案6】:

就我而言,这是由于大写/小写字母混淆而发生的。 用户模型有这个:

const userSchema = new Schema(
// ...
);
module.exports = mongoose.model('User', userSchema);

并且 Product 模型引用了 User 模型,但小案例:

const productSchema = new Schema(
// ...
  userId: 
    type: Schema.Types.ObjectId,
    ref: 'user', // This should exactly match the name of User model above!!!
    required: true
  
);

【讨论】:

我很感激...我在模式关联参考中使用了gearItem...但是模型本身被命名为GearItem...哎呀?感谢您提供这个额外的答案!跨度> 救了我。虽然我之前在其他项目中这样做过,但我错过了这个花了 3 个小时才弄清楚的小部分。【参考方案7】:

我在使用 ES6/Typescript 时也遇到过这个错误。即使我导入了模型,错误仍然存​​在。根据文档here

MongooseError.MissingSchemaError

当您尝试访问尚未注册的模型时抛出

    import  model, Schema  from 'mongoose';
    import Company from './CompanyModel';

    const ProjectSchema = new Schema(
        company:  type: Schema.Types.ObjectId, ref: "Company" 
    );

    export default model('Project', ProjectSchema);

提示只是为了确保明确使用模型,因此将 ref:"Company" 更改为 ref:Company.modelName 似乎解决了问题。

希望对大家有所帮助

【讨论】:

【参考方案8】: 您需要在代码中要求您的模型 在您调用 mongoose.model 之前,Mongoose 不会识别您已定义模型,并且只有在您需要模型时才会调用它

例如。

在下面的例子中,如果你不做const Role = require("./role");,你会得到MissingSchemaError: Schema hasn't been registered for model “Role”

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Role = require("./role");
const userSchema = new Schema(
  
    role:  type: Schema.Types.ObjectId, ref: "Role", required: false ,
    username:  type: String, required: true, trim: true ,
    password:  type: String, required: true, trim: true ,
    email:  type: String, required: true, trim: true 
  ,
   timestamps: true 
);

module.exports = mongoose.model("User", userSchema);

【讨论】:

【参考方案9】:

在使用 express 时,一个常见的错误是在 mongoose 之前要求 express。这将导致“MissingSchemaError:尚未为模型“用户”注册模式。”错误。

您可以通过更正“要求”顺序(即猫鼬然后快递)轻松修复它

var mongoose = require('./config/mongoose'), 
    express = require('./config/express');

【讨论】:

就是这样...这是最简单的解决方案。谢谢@bwaaaaaa【参考方案10】:

我在尝试使用 mongoose-fixture 将一些默认数据播种到 mongo 集合中时遇到此错误。困惑了很长时间,跟随这个和类似的线程寻求帮助,试图调试。最终,在我的情况下,问题出在mongoosemongoose-fixture 版本。

如果没有代码更改帮助,或者如果您在尝试正确使用 mongoose-fixture(它应该为您注册您的模式)时遇到此错误,请尝试此操作。删除项目的node_modules 目录,运行npm cache clean,然后运行npm install

如果即使这样也没有帮助,请尝试比较有问题的应用程序和有效应用程序之间的mongoose / mongoose-fixture 版本,并尝试更改package.json 中的版本,然后重复上述步骤。这对我有用。

【讨论】:

【参考方案11】:

我最近遇到了一个类似于 @rajkumar-nagarajan 和 @verybadalloc 提供的答案的解决方案。

我更喜欢这种方法,因为它避免了 n+1 次迭代,并且不会从文件系统中读取所有模型。

app/models/index.js,需要每个模型文件:

require('./model1');
require('./model2');
require('./model3');

然后,在/app.js/index.js(无论您的项目使用哪个),您现在可以简单地执行以下操作:

require('./app/models');

我缺少的部分(此处赞赏任何提示)--如何按名称轻松注册每个模型,例如:

mongoose.model('Model1')

【讨论】:

【参考方案12】:

我犯了一个不同的错误,就像我创建了架构一样,但问题是我没有使用架构模型(用于插入、更新、读取和删除文档)。

即我创建了类似的集合:

const playerSchema = new Schema(
    bowling: 
        style: String,
        arm: String,
    
)

export const PlayerSchema = model('Player', playerSchema)

但没有在某处使用或调用 PlayerSchema 模型,这就是我收到此错误的原因。

【讨论】:

我想你的意思是你没有使用或打电话给playerSchema(不是PlayerSchema)。【参考方案13】:

我在尝试在本教程User Auth on MEAN stack 的基础代码上添加新模型时遇到了这个问题。解决方案就像Ahei 提到的那样。

具体来说,我需要在/app_api/models/db.js 的末尾添加一行require('path/to/your/model'),这在app.js 中是必需的。为了便于开发,最好保持结构的一致性。

【讨论】:

【参考方案14】:

我尝试了上述所有解决方案,但都失败了,我发现解决方案是清除我的数据库(MongoDB),然后重新运行应用程序

【讨论】:

【参考方案15】:

问题出现在模型的require() 语句中。您需要像这样将所有 MongoDB 依赖项移动到路由依赖项之上,例如

//blog.js file

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

const blogSchema = new Schema(
title : String
);

mongoose.model('blogs', blogSchema);

在 server.js 中

//server.js file
require('dotenv').config();
const mongoose = require('mongoose');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
require('./models/blog');
const Blog = mongoose.model('blogs');

const URL = process.env.MONGO_DB_URL;
 mongoose.connect(URL, 
  useNewUrlParser: true,
  useUnifiedTopology: true,
);

mongoose.connection
.once('open', () => console.log('Connected to MongoLab instance.'))
.on('error', (error) => console.log('Error connecting to MongoLab:', error));

const app = express();

app.use(cors());
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.get('/',  (req,res)=>
res.send('Hello World')
);

 app.post('/blog',async (req, res) =>
    const blog = await new Blog(req.body).save();
    res.send('just an example');
  );

【讨论】:

【参考方案16】:

如果您因架构中的 ref 字段而面临此错误,您需要提供用于该建模参考架构的确切名称(区分大小写)。

// models/User.js
const userSchema = new Schema( name: String );
module.exports = mongoose.model('User', userSchema); // note the 1st arg


// models/Post.js
const postSchema = new Schema( 
   user:  
     type: mongoose.Schema.Types.ObjectId, 
     ref: 'User' // `ref` must be 'User' not 'user'
   ,
)

module.exports = mongoose.model('Post', postSchema)

还有 在查询时调用.populate() 时,必须在调用参考模型之前对其进行建模。 这是因为models/User.js 不会在此处的其他任何地方执行,因此通过导入您将使Usermongoose.models 对象中可用。

在实际项目中,User 模型文件在整个项目中至少导入一次,因此请确保您至少导入了一次参考模型。

// your app
const User = require('./models/User') // important to import
const Post = require('./models/Post')

//console.log(!!mongoose.models.User) // true
//..
const post = await Post.findOne().populate( path : 'user' )

另一种方法是在Post 模型中导入User 模型并将其用于ref 字段。

// models/User.js
const userSchema = new Schema( name: String );
module.exports = mongoose.model('User', userSchema);


// models/Post.js
const User = require('./User')

const postSchema = new Schema( 
   user:  
     type: mongoose.Schema.Types.ObjectId, 
     ref: User, // here we are directly referring model instance itself instead of model name.
   
);

module.exports = mongoose.model('Post', postSchema)

& 当然有很多方法可以解决这个问题。

【讨论】:

【参考方案17】:

如果您使用的是 Mean.js 堆栈,请使用以下命令运行测试:

grunt test

而不是

mocha

【讨论】:

这与测试无关。

以上是关于MissingSchemaError:尚未为模型“用户”注册架构的主要内容,如果未能解决你的问题,请参考以下文章

Nestjs中的MissingSchemaError

在 Node JS 中填充 Mongoose

Passport.js 抛出错误,MissingSchemaError(name)

使用 mongoose-observer 库时出现 MissingSchemaError

尚未为模型“ResourceSchema”注册架构。 - 嵌套js

致命错误:尚未为模型“a”注册架构。使用 mongoose.model(name, schema)