猫鼬模式还没有注册为模型

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

npm start

我得到一个例外,说:

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

这是我在/model/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);
129831 次浏览

It's not an issue with model export. I had the same issue.

The real issue is that require statements for the models

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

were below the routes dependencies. Simply move the mongoDB dependencies above the routes dependencies. This is what it should look like:

// 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();

If someone coudn't fix it with the approach of the correct answer (like me), try to look at the creation of the schema. I wrote the 'ref' as 'User', but the correct was 'user'.

Wrong:

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

Correct:

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

Elaborating on Rafael Grilli's answer above,

Correct:

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');

IF YOU USE MULTIPLE mongoDB CONNECTIONS


beware that when using .populate() you MUST provide the model as mongoose will only "find" models on the same connection. ie where:

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' },
});


// model creation - notice the registered model name as first parameter
var User = db1.model('_users_', userSchema);
var Customer = db2.model('_customers_', customerSchema);

Correct approach:

// you can pass a model instance
Customer.findOne({}).populate('created_by', 'name email', User)
Customer.findOne({}).populate({ path: 'created_by', model: User })


// you can pass the model NAME as string (even from variable)
Customer.findOne({}).populate({ path: 'created_by', model: '_users_'


var otherSchemaName = '_'+'users'+'_'
Customer.findOne({}).populate({ path: 'created_by', model: otherSchemaName})

Incorrect (produces "schema hasn't been registered for model" error):

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

You should also check that you don't have dirty data in your database. I ended up with a document containing the lowercased version of the referenced model (user instead of User). This causes the error and is incredibly hard to track down.

Easy to fix with a quick mongo query:

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

In my case, this issue because I haven't included the model or ref model into the application. So you should required Post model and Comment model in your node application.

.\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

I got this error resolved when use setTimeout on server.js

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);

I used the following approach to solve the issue

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);

Please look, here ref don't have string type value, now it's referring to Comment schema.

This error also pops up when we create wrong references (ref) between mongoose models.

In my case I was referring to the file name instead of model name.

eg:

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

We should refer to 'user' (model name) instead of 'User' (file name);

Refer the same name that you refer in model name while creating new model.

For example: if I have mongoose model like:

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

Then I have to refer to posts collection via writing ref:"post".

Here's https://mongoosejs.com/docs/populate.html#cross-db-populate

It says we have to pass the model as a third argument.

For e.g.

//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);

I also facing same issue but i resolved by removing module.exports

module.exports = mongoose.model('user', userSchema); // remove module.exports
and use 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

The issue is with the refs, always make sure to refer the refs to whatever name your are exporting from the models.

// Model

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

//Refs

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

});

My problem was sort out using the below

adminModel.findById(req.params.id).populate({ path: "users", model: userModel //User collection name })

I was also facing the same problem. The solution to my problem was looking at the ref parameter which had a different name compared to the model I was actually exporting and hence no such model was found.

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

Whereas what I had actually exported was :-

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


module.exports = Tasks

After rectifying the Task as Tasks my problem was solved

Just wanted to add that for me I was using destructuring when importing the Schema which was causing it to fail.

Correct

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

Incorrect

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

You're not giving the model any value

In my case, I was using a model for which I didn't updated when making the MongoDB connection.

So, I had something like

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

with this connection

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

Fix

You have to add the model to the conn when initiating the connection

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

Note that I added Device to the connection.

this problem happens when you use a model that depends on another model, but that other model didn't get registered yet.

a simple fix would be adding model to popualte instead of depending on ref in the schema

=>> example

const jobs = await Job.find({}).populate({
path: "jobDescriptions",
model: JobDesc,
select: "list",
populate: {
path: "list",
select:"name list",
model: Skill,
},
});
import User from '..'


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

This answer works for me. However You're going to have to import the model instead of setting it into cote

I just face the same problem. I created reviews for products. then I deleted them. whenever mongoose tried to populate the data of deleted items Mongoose Schema hasn't been registered for model error was showing. After dropping the review collection the error was gone.