MissingSchemaError: Schema hasn't been registered for model "farm" - node.js

I have a database where I have two collections : farms and products.
Farms are associated to the product and products have multiple farms where they can be found.
The below code is from products.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
min: 0,
},
category: {
type: String,
lowercase: true,
enum: ["fruit", "vegetables", "dairy"],
},
farm: [
{
type: Schema.Types.ObjectId,
ref: "farm",
},
],
});
const Product = mongoose.model("Product", productSchema);
module.exports = Product;
I have a get route that takes the id from req.params and finds the product using ID as a reference which works fine. However, whenever I try to populate the product with "farm" I get the Schema hasn't been registered error. However, whenever I check the mongo collections I can see that that it is associated with the farm.
I cross checked the schema and I think I have correctly exported the schema but I keep hitting the MissingSchema Error and just can't find where the error is.
This is my code where I am hitting an error.
const mongoose = require("mongoose");
const Farm = require("./models/farm");
const Product = require("./models/products");
app.get("/products/:id", async (req, res, next) => {
const { id } = req.params;
const products = await Product.findById(id).populate("farm");
console.log(products);
res.render("product/details", { products });
});
If I exclude the populate method the product details are being show but everytime I include the populate method I get this error
UnhandledPromiseRejectionWarning: MissingSchemaError: Schema hasn't been registered for model "farm".

When you created the FarmSchema model did you name it ‘Farm’?
const Farm = mongoose.model(‘Farm’, FarmSchema)
When you reference that model in the ProductsSchema you have called it ‘farm’, lowercase which is a different variable, it will need to be the same as the variable used to create the model.
farm: [
{
type: Schema.Types.ObjectId,
ref: "farm", // this should be; ref: “Farm”
},

Related

Populate array inside object in mongoose

I have a company model which looks like this:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const CompanySchema = new Schema(
{
companyName: String,
settings: {
type: {
priceVisible: Boolean,
allowPickupAddressAddition: Boolean,
paymentMethodsAvailable: [
{ type: Schema.Types.ObjectId, ref: "PaymentMethod" },
],
},
},
}
);
const Company = mongoose.model("Company", CompanySchema);
module.exports = Company;
And I want to populate the values store in paymentMethodsAvailable array. Here is relevant controller code:
const company = await Company.findOne({ _id: id }).populate([
{
path: "settings",
populate: [{path: "paymentMethodsAvailable"}]
},
]);
But this doesn't work as expected. I can see that it might be trying to populate settings object, and fails there. Is there a way in which I can tell mongoose to populate settings.paymentMethodsAvailable ?
Try this
const company = await Company.findOne({ _id: id }).populate(
"settings.paymentMethodsAvailable"
);
You can find more examples in the documentation. I was using this section as a reference https://mongoosejs.com/docs/populate.html#populating-maps
Mongoose provides clear syntax
The following code will work fine
const company = await Company.findOne({ _id: id }).populate(
"settings.type.paymentMethodsAvailable"
);
if(!company) {
// if there is no company with that id
// this acully not error it's simply
// return `null` to tell you company not found.
res.status(404).send()
}
Also: you can go further and populate specific fields inside settings.paymentMethodsAvailable
const company = await Company.findOne({ _id: id }).populate(
"settings.type.paymentMethodsAvailable",
"field1 filed2 filed3"
);

Not able to save my array in to mongodb database

I am new in backend development, creating a post API by using node js and MongoDB,
This is my schema model
// restaurantSchema.js
const mongoose = require('mongoose');
const foodSchema = new mongoose.Schema({
categoryName:{
type: String,
required: true
},
dish: [
{
dishName: {
type: String,
required: true
},
dishDescription: {
type: String
},
dishPrice: {
type: Number,
required: true
},
// dishImg: {
// type: String,
// },
dishRating: {
type: String
},
}
]
});
const restaurantSchema = new mongoose.Schema({
restaurantName: {
type: String,
},
restaurantRating:{
type: String
},
restaurantAddress: {
type: String
},
category: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'foodSchema'
}
]
})
const Restaurant = new mongoose.model('RESTAURANT', restaurantSchema);
module.exports = Restaurant;
here is the router code
// auth.js
const express = require('express');
const router = express.Router();
require('../db/conn');
const Restaurant = require('../model/restaurantSchema');
const app = express();
router.post('/post-food', async (req, res) => {
try {
console.log(req.body, "body")
const restaurant = new Restaurant({
restaurantName: req.body.restaurantName,
restaurantRating: req.body.restaurantRating,
restaurantAddress: req.body.restaurantAddress,
category: [
{
categoryName: req.body.categoryName
},
{
dishName: req.body.dishName,
dishDescription: req.body.dishDescription,
dishPrice: req.body.dishPrice,
dishRating: req.body.dishRating
}
]
});
await restaurant.save();
console.log(restaurant, "save")
res.status(201).json({ message: "food added successfully" })
} catch (err) {
console.log(err)
}
})
module.exports = router;
this code is going to the app.js (main file)
I am getting only this data while I comment out the category(array) in the auth.js file otherwise not able to save any data in the database file
[1]: https://i.stack.imgur.com/wKn9p.png
First of all this is a great question with very valid code, nicely done!
So, everything is correct in your code except you should declare your foodSchema as a mongoose model as well, just like you're doing so with this one
const Restaurant = new mongoose.model('RESTAURANT', restaurantSchema);
You don't need to use new, you can just omit it.
So basically next to this add the declaration for your foodSchema it should look something like this:
const Restaurant = mongoose.model('RESTAURANT', restaurantSchema);
const Food = mongoose.model('FOOD', foodSchema)
and for exporting them you could do something like this:
module.exports = {
Restaurant: Restaurant,
Food: Food
}
For importing any of these two in your router file you could use destructuring:
const { Restaurant } = require('../model/restaurantSchema')
I hope this helps, have a good day!
You have declared category as a list of mongoose typeId and inserting a list of object of type foodSchema. In your schema file after declaring foodSchema, create a model using that food schema.
const Food = mongoose.model('FOOD', foodSchema)
and now in restaurant schema the category will refer ref: 'Food'
mongoose expecting category as ["61407ce0b6c1fc83d896002e"] but you are providing
[{
categoryName:{
type: String,
required: true
},
dish:[...]
}]
export both Food and Restaurant from the schema file.
module.exports = Food;
for creating restaurant first create an Food
const food = new Food({
categoryName: req.body.categoryName,
dish: [ {
dishName: req.body.dishName,
dishDescription: req.body.dishDescription,
dishPrice: req.body.dishPrice,
dishRating: req.body.dishRating
} ]
})
let foodInserted = await food.save();
then the foodInserted._id to the category of restaurant.
const restaurant = new Restaurant({
restaurantName: req.body.restaurantName,
restaurantRating: req.body.restaurantRating,
restaurantAddress: req.body.restaurantAddress,
category: [foodInserted._id]
});
Follow this documentation

MissingSchemaError: Schema hasn't been registered for model "Review". Use mongoose.model(name, schema) [duplicate]

I'm using the MEAN stack and when I try to start the server using npm start, I get an exception saying that:
schema hasn't been registered for model 'Post'. Use mongoose.model(name, schema)
Here is my code inside /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);
as I can see the schema should be registered for the model 'Post', but what is causing the exception to be thrown?
Edit: Here's the exception error:
/home/me/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)
and here's the app.js code with the mongoose initialization:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');
before the line:
app.use('/', routes);
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'
}
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', select: 'name email', model: User })
// you can pass the model NAME as string (even from variable)
Customer.findOne({}).populate('created_by', 'name email', '_users_')
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');
It seems Mongoose have now included this case in their docs based on this answer ;)
see: https://mongoosejs.com/docs/populate.html#cross-db-populate
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.
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);
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,
},
});
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
});
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);
.\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);
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 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
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');
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.
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".
My problem was sort out using the below
adminModel.findById(req.params.id).populate({
path: "users",
model: userModel //User collection name
})
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.
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.
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

Filter moongose results by reference field using express

I need filter the products of a collection by category id which is a reference field.
product.js
const restful = require('node-restful')
const mongoose = restful.mongoose
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
category: {type: mongoose.Schema.Types.ObjectId, ref: 'CategoryProduct'}
})
productSchema.pre('find', function () {
this.find().populate('category')
})
module.exports = restful.model('product', productSchema)
routes.js
const express = require('express')
const auth = require('./auth')
module.exports = function (server) {
const protectedApi = express.Router()
server.use('/api', protectedApi)
const Product = require('../api/product/productService')
Product.register(protectedApi, '/products')
}
If I run this on Postman, http://localhost:3003/api/products/?name__regex=/test/i, I can get all products which contains 'test' on name.
So I try get all products by a specific category doing this, http://localhost:3003/api/products/?category=5af3ac4372edc6000468d766.
But as the category is an objectID, I receive this error:
{
"message": "Cast to ObjectId failed for value \"5\" at path \"category\" for model \"SimpleProduct\"",
"name": "CastError",
"stringValue": "\"5\"",
"kind": "ObjectId",
"value": 5,
"path": "category"
}
How do I filter the products by category? I do not know how to treat this parameter correctly and pass to mongoose
Here is my CategoryProduct.js file
const restful = require('node-restful')
const mongoose = restful.mongoose
const categorySchema = new mongoose.Schema({
name: {type: String, required: 'O campo Categoria é obrigatório'},
status: {type: Number, required: true},
updated_at: {type: Date}
})
module.exports = restful.model('CategoryProduct', categorySchema)
you would have to do the following in your route:
const mongoose = require('mongoose');
router.get('/', (req, res, next) => {
const category = req.query.category; // assign the query param for use
// mongoose query now
Product.find({category: mongoose.Types.ObjectId(category)}, (err, result) => {
if (err) {console.log(err)};
if (result) {
res.json(result);
}
});
});
This is just a basic example. Since you are using node-restful you might have to adjust the code but the main idea here is that you require the mongoose module using
const mongoose = require('mongoose')
then pass your category query param to it to convert the string to objectID using:
mongoose.Types.ObjectID(YOUR_CATEGORY_PARAM_HERE)
You can do this anywhere, in the your routes.js or in your express.js, just have to have the string you want to convert :)
hope that helps :).

MissingSchemaError: Schema hasn't been registered for model "User". when trying to execute the code at CLI [duplicate]

I'm using the MEAN stack and when I try to start the server using npm start, I get an exception saying that:
schema hasn't been registered for model 'Post'. Use mongoose.model(name, schema)
Here is my code inside /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);
as I can see the schema should be registered for the model 'Post', but what is causing the exception to be thrown?
Edit: Here's the exception error:
/home/me/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)
and here's the app.js code with the mongoose initialization:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');
before the line:
app.use('/', routes);
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'
}
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', select: 'name email', model: User })
// you can pass the model NAME as string (even from variable)
Customer.findOne({}).populate('created_by', 'name email', '_users_')
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');
It seems Mongoose have now included this case in their docs based on this answer ;)
see: https://mongoosejs.com/docs/populate.html#cross-db-populate
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.
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);
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,
},
});
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
});
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);
.\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);
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 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
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');
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.
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".
My problem was sort out using the below
adminModel.findById(req.params.id).populate({
path: "users",
model: userModel //User collection name
})
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.
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.
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

Resources