Related
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
How can i execute this mongodb query through node js (mongoose).
i have two tables with the follwoing schemas,
i want to fetch username and password from users table and fetch full name from the info table.
var infoSchema = mongoose.Schema({
khatam_id: String,
user_id: String,
fullname: String,
});
var usersSchema = mongoose.Schema({
user_id: String,
username: String,
password: String,
});
i don't know if you're a hot shot but if you are you can use this.
userSchema.virtual('infos',
{
ref: 'Info',
localField: 'user_id',
foreignField: 'user_id',
})
Assuming u name you're infoSchema as Info model ,mongodb converts it to infos in case you didn't know thats why the virtual field will be called as infos ref obviously a reference to Info model
localField is the field referring the userSchema unique id and foreignField is the field u are referring in the infoSchema which matches the unique value that localfield u mentioned .
Finally, along with all the fields in your userSchema add this
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
so when u query for user
Give it a shot it really comes in handy.
Note: it doesn't actually create a field in the database (virtual duh.) it just populates your response object for front end rendering which is actually better.
Connect to MongoDB: Make sure MongoDB service is running before the program execution.
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/your-database");
mongoose.Promise = global.Promise;
var connection = mongoose.connection;
connection.once('open', function() {
console.log('connected to database);
});
connection.on('error', function() {
console.error('Mongoose connection error");
});
process.on('SIGINT', function() {
mongoose.connection.close(function() {
console.log('Mongoose connection disconnected due to app SIGINT.');
});
});
create user schema :
const Schema = mongoose.Schema;
const usersSchema = new Schema({
user_id: String,
username: String,
fullname: String
});
const Users = mongoose.model('Users', usersSchema );
Run Query like this:
Users.findOne({query})
.then(function(user){
// do something
})
.catch(function(err){
// handle error
})
Assuming you know how to set setup mongoose and connect your database and only need the correct query let me share something i noticed with the models you provided. I don't think there is a need for 2 collections as you can store the same thing under one collection because it saves the time for lookup for the user data from info schema. So user schema can be
var usersSchema = mongoose.Schema({
user_id: String,
username: String,
password: String,
khatam_id: String,
fullname: String
});
And using the following query you can get the user details
Users.findOne({})
.then(function(user){
// do something
})
.catch(function(err){
// handle error
})
This is much more efficient and faster compared to using aggregate queries or mongoose populate functions.
If the above method is not suitable for you you can try the mongoose populate function.
UserSchema = new mongoose.Schema({
user_id: String,
password: String,
},
// schema options: Don't forget this option
// if you declare foreign keys for this schema afterwards.
{
toObject: {virtuals:true},
// use if your results might be retrieved as JSON
// see http://stackoverflow.com/q/13133911/488666
//toJSON: {virtuals:true}
});
UserInfoSchema = new mongoose.Schema({
user_id: String,
khatam_id: String,
username: String,
fullname: String,
});
// Foreign keys definitions
UserSchema.virtual('userDetails', {
ref: 'UserInfoSchema',
localField: 'user_id',
foreignField: 'user_id',
justOne: true // for many-to-1 relationships
});
// Models creation
var UserSchema = mongoose.model('UserSchema', UserSchema);
var UserInfoSchema = mongoose.model('UserInfoSchema', UserInfoSchema);
// Querying
UserSchema.find({...})
// if you use select() be sure to include the foreign key field !
.select({.... user_id ....})
// use the 'virtual population' name
.populate('userDetails')
.exec(function(err, books) {...})
install mongoose in your machine
npm install mongoose
import mongoose lib
const mongoose = require('mongoose');
const Schema = mongoose.Schema, ObjectId = Schema.ObjectId;
connect to mongodb and create schema for your table
mongoose.connect('mongodb://localhost/myappdatabase');
const usersSchema = new Schema({
_id: ObjectId,
user_id: String,
username: String,
fullname: String
});
const Users = mongoose.model('Users', usersSchema );
Find user from "Users" table using mongo query
Users.find({<here you can write your mongo query>}, function (err, docs) {
// docs.forEach
});
you have to use aggregate
db.users.aggregate([
{
$lookup:
{
from: "info",
localField: "user_id",
foreignField: "_id",
as: "userInfo"
}
},
{ "$unwind": "$userInfo" },
])
You can use this query to get those types of records what you want:
db.users.aggregate([
{ $lookup: {
from: "info",
localField: "user_id",
foreignField: "user_id",
as: "userInfo"}},
{ "$unwind": "$userInfo" }])
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
I want to use mongodb on my new project. That is first time, im using mongodb. In relational databases i was saving datas like:
tbl_country > id,name,created_at,etc..
tbl_city > id,country_id,name,created_at,etc...
tbl_user > id,name_surname,city_id,etc...
In this schema i can find a city's country, a user's country, etc... via using foreign keys.
Which way do you suggest to create a schema like this in best performance by nodejs w/ mongodb ?
You can still use foreign keys when you create your schemas. Please check this schemas as examples you have given.
var CountrySchema = new Schema({
name: String,
created_at: Date
});
var CitySchema = new Schema({
countryName: { type: mongoose.Schema.Types.ObjectId, ref: 'Country' },
created_at: Date
});
var UserSchema = new Schema({
name_surname: String,
city: { type: mongoose.Schema.Types.ObjectId, ref: 'City' }
})
mongoose.model('Country', CountrySchema);
mongoose.model('City', CitySchema);
mongoose.model('User', UserSchema);
and when you fetch data, you have to use 'populate' method. For instance:
City.find()
populate('countryName', 'name') // It will bring only name field
.exec(function(err, cities) {
})
Btw. _id s are automatically created by mongo for each data. So you do not need to add id field into your schemas. Hope it helps. Good luck
I'm currently trying to develop an app using mongo and node.js.
I am facing a problem when I want to build a query who use the populate option.
Here are my Schemas :
// Schema used by mongoose
var userSchema = new mongoose.Schema(
{
_id: mongoose.Schema.Types.ObjectId,
login: String,
password: String,
movies: [ { type: mongoose.Schema.Types.ObjectId, ref: movieModel} ],
admin: Boolean
},{ collection: "user" });
var movieSchema = new mongoose.Schema(
{
_id: mongoose.Schema.Types.ObjectId,
title: String,
}, { collection: "movie" });
As you can see, each user have an array of movies, this array contains valid ids of movies. What I want is to have the movies of an user. This is how I build my query :
var query = userModel.findOne({ login: req.session.user["login"] })
.populate("movies");
query.exec(function(err, user)
{
if (err)
throw err;
console.log(user.movies[0].title);
});
The query is executed successfully, but when I try to display the title of the first movie at the console.log line I got an error "TypeError: Cannot read property 'title' of undefined". I checked the documentation of mongoose and don't understand why I'm getting this error.
I would like to specify that my database contains valid data.
I put mongoose in debug mode, and this is the query that is executed :
Mongoose: user.findOne({ login: 'user' }) { fields: undefined }
Mongoose: user.find({ _id: { '$in': [ ObjectId("52e2a28949ad409834473e71"), ObjectId("52e2a28949ad409834473e79") ] } }) { fields: undefined }
The two ids on the second line are valid ids of movies. I would like to display their name.
Thanks a lot for your help.
What is the value of this: ref: movieModel?
movieModel would need to be set to the string like "Movie". See here for more information. It will need to match the identifier provided when you create the Movie model.
var Movie = mongoose.model('Movie', movieSchema);
So, you might have in a schema:
var userSchema = mongoose.Schema({
name: String,
favorite_movies: { type: Schema.Types.ObjectId, ref: 'Movie' }
});
var User = mongoose.model('User', userSchema);
I've used the string Movie in both the Schema definition and when creating the Movie type. They need to be exactly the same.
MongooseJs uses the string name of the Model to determine where to fetch the documents from when using ref and populate.
In the debug output, you can see how Mongoose is actually querying the wrong collection, as I'd expect it to be using movies.find to find the relevant Movie documents.