Following is my Schema -
var mongoose = require('mongoose');
// Create Schema
var userSchema = new mongoose.Schema({
name: String,
email: String,
created_by: { type: Schema.Types.ObjectId, ref: 'User'},
created_date: { type: Date, default: Date.now }
});
// compile Schema into a model
var User = mongoose.model('User', userSchema);
// Make this instance available when require()d
module.exports = User;
Following is the error I am getting -
/trialcoder/project/server/models/user.js:26
created_by: { type: Schema.Types.ObjectId, ref: 'User'},
^
ReferenceError: Schema is not defined
at Object.<anonymous> (/trialcoder/project/server/models/user.js:26:25)
Let me know what I am doing wrong as currently I am following the second approach reference here
FYI - I deleted some fields so line number may not be the same here.
Schema doesn't exist, you need to use: mongoose.Schema.Types.ObjectId to access the object reference, or create a variable with that name and store moongoseSchema in it.:
var moongose,
Schema = `mongoose.Schema`;
Related
Making an app with a variety of schemas, many having other objects (Schema.Types.ObjectIds) as their properties.
When doing this, I can access the sub-object's property, as long as that sub-object's property is a string. But I'm having issues with it if that sub-object's property is yet another object (and then I need to query properties from that, string or not). For example, the first works fine:
user schema-> friends property of user (which is a list of user objects) -> username property of friend (which is a string)
But this I'm having issues with, I'm getting a string id and not the actual object**:
user schema-> profilePosts property of user (which is a list of profilePost objects) -> author property of profilePost (which is a user object)** -> author username property of profilePost (which is a string)
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: {type: String, required: true},
password: {type: String, required: true},
friends: [{type: Schema.Types.ObjectId, ref: "User"}],
profilePosts: [{type: Schema.Types.ObjectId, ref: "ProfilePost"}],
friendRequests: [{type: Schema.Types.ObjectId, ref: "User"}],
})
module.exports = mongoose.model('User', UserSchema);
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ProfilePostSchema = new Schema({
date: {type: Date, required: true},
author: {type: Schema.Types.ObjectId, ref: "User"},
content: {type: String, required: true},
comments: [{type: Schema.Types.ObjectId, ref: "ProfilePostComment"}],
likes: [{type: Schema.Types.ObjectId, ref: "User"}],
hostProfile: {type: Schema.Types.ObjectId, required: true,ref: "User"},
})
module.exports = mongoose.model('ProfilePost', ProfilePostSchema);
exports.user_friends_render = async (req,res) => {
try {
const ViewedProfile = await User.find({}, 'username friends profilePosts friendRequests').populate('friends').populate('profilePosts').populate('friendRequests');
res.status(200).json(ViewedProfile);
} catch(error) {
res.status(200).json({message: error.message});
}
}
objects are string ids instead of objects
Mongoonse populate root object but not implicit deep populate
You can replace string by object as argument at populate method,
for provide full path to populate
const ViewedProfile = await User
.find({}, 'username friends profilePosts friendRequests')
.populate('friends')
.populate({
path: "profilePosts",
populate: [
{
path: "author",
// model: UserModel
},
{
path: "comments",
// model: ProfilePostCommentModel
},
{
path: "likes",
// model: UserModel
},
{
path: "hostProfile",
// model: UserModel
}
]
})
.populate('friendRequests');
You can see fully post at this problem.
In a user schema, I need to define a field of contacts with a blocked property.
My actual definition goes like this:
const UserSchema = new Schema({
id: Schema.Types.ObjectId,
// Other fields
// ...
contacts: [{
type: Schema.Types.ObjectId,
ref: 'User'
}]
}
const UserModel = mongoose.model('User', UserSchema);
From there I was unable to find a possible way to add the blocked field in the same referenced relationship contacts. Is it necessary to create an Intermediary Collection to add the additional field to the relation?
I ended up creating a contact collection which holds at the same time a reference to the user plus the additional fields that I need:
//user.js
const UserSchema = new Schema({
id: Schema.Types.ObjectId,
// Other fields
// ...
contacts: [{
type: Schema.Types.ObjectId,
ref: 'Contact'
}]
}
const UserModel = mongoose.model('User', UserSchema);
//contact.js
const ContactSchema = new Schema({
id: Schema.Types.ObjectId,
contact: {
type: Schema.Types.ObjectId,
ref: 'User'
},
blocked: {
type: Boolean,
required: true
}
}
const ContactModel = mongoose.model('Contact', ContactSchema);
I have two mongoose schemas 'user' and 'project' and i want to show relationship between these schemas like in mysql. How to do this?
And how can i pass user while creating a project?
User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Schema = mongoose.Schema();
const UserSchema = mongoose.Schema({
fullname: {type: String},
username : {type:String},
password: {type:String}
});
UserSchema.methods.encryptPassword = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(10), null);
};
UserSchema.methods.comparePassword = function(userPassword, cb) {
bcrypt.compare(userPassword, this.password, (err, isMatch) => {
if(err) throw err;
cb(null, isMatch);
});
}
module.exports = mongoose.model('User', UserSchema);
project.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema();
const User = require('./user');
const ProjectSchema = mongoose.Schema({
title: {type: String, required: true},
description: {type:String},
created_at: { type: Date, default: Date.now },
publish : { type: Boolean, default: false}
});
module.exports = mongoose.model('Project', ProjectSchema);
Creating schema in Mongoose isn't like creating schema in Relational DBMS, such as MySQL, PostGreSQL.
You can use objectId, bro.
If one project just can be handled by one user, you can use something like this.
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
But if one project is handled by multi users
users: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}]
Hope it will help
Schema Change
To create a relationship in Mongoose (MongoDB), create a property on your schema with the following properties
1. type: mongoose.Schema.Types.ObjectId
2. ref: "string name of the Collection this reference lives in"
For example, if you wanted a project to contain a reference to the users inside of it, you could do the fallowing
const mongoose = require('mongoose');
const Schema = mongoose.Schema();
const User = require('./user');
const ProjectSchema = mongoose.Schema({
title: {type: String, required: true},
description: {type:String},
created_at: { type: Date, default: Date.now },
publish : { type: Boolean, default: false},
users: [{type: Schema.Types.ObjectId, ref: 'User'}]
});
module.exports = mongoose.model('Project', ProjectSchema);
Example Opertaion
Given the above Schema, if you wanted to create a new Project and add users to it during creation, you would need to have those users' _id properties on hand (i.e. cached). That could mean making a prior query to the db to get all the users who will be a part of this project or having some client send you the user ids.
A much better option would be to create a project, and update its' users property as users are added or removed.
Here is a quick example
const Project = require('./models/Project.js');
let userIds = // get the user _ids some how
Project.create({
title: 'A sample',
description: 'The usual',
publish: true,
users: userIds
})
.then(callback);
I have several schemas defined. Here's one that works fine:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var NewsSchema = new Schema({
name: String,
route: String,
remoteURL: String,
articles: [{title: String, link: String, Image: String, contentSnippet: String}],
retrieved: Date,
dormant: { type: Boolean, default: false}
});
module.exports = mongoose.model('News', NewsSchema);
Here's a second one that's nearly identical:
var mongoose = require('mongoose'),
Schema = mongoose.Schema
// NewsSchema = new Schema({ name: String });
var ArticlesSchema = new Schema({
title: String,
link: String,
pubDate: Date,
image: String,
contentSnippet: String,
sourceName: String
// sourceId: [ {type: Schema.Types.ObjectId, ref: NewsSchema}]
});
module.exports = mongoose.model('Articles', ArticlesSchema);
I've loaded both of the modules at the top of my program, along with a bunch of other stuff like this:
players = require('./app/models/players'),
articles = require('./app/models/articles'),
If I create an instance of the first one with something like:
var player = new Players();
But if I try to create an instance of the second one with:
var item = new Articles();
I receive the error in the subject. In tracing the code I can see that the modules are in scope, so I don't believe it's something stupid like redefining a variable or something like that.
Any ideas?
There is a missing quote mark, so
Instead of
sourceId: [ {type: Schema.Types.ObjectId, ref: NewsSchema}]
use
sourceId: [ {type: Schema.Types.ObjectId, ref: 'NewsSchema'}]
would solve your problem.
I'm using mongoose.js on a node.js server connecting to mongodb and
I have a mongoose model like the following
SubSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
mongoose.model('SubModel', SubSchema);
MainSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
subs: [SubSchema],
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
var MainModel mongoose.model('MainModel', MainSchema);
which i pull with a command like this
var q = MainModel.find({})
.sort('created', -1)
.limit(25)
.populate("_member")
.populate("subs._member")
.populate("subs.members");
q.execFind(function(err, mains){
//mains[0].subs[0].members - will always be empty why?
});
my problem is that i can't get subs.members array to populate or even load, it just keeps showing as an empty array.
I've tried .populate("subs.members") to no avail even though subs._member loads just fine
try this
SubSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
var SubModel = mongoose.model('SubModel', SubSchema);//add
MainSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
subs: [SubSchema],
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
var MainModel = mongoose.model('MainModel', MainSchema);
MainModel.find({})
.sort('created', -1)
.limit(25)
.populate("_member")
.populate("subs._member")
.exec(function(err, mains){
//add
SubModel.populate(mains,{
path:'subs.members'
},function(err,mains){
//mains[0].subs[0].members - is not empty
});
});
#leesei: I can't comment on your post (too little rep), so I leave this as a separate answer.
In mongoose 3.6 subdoc population still doesn't work, the issue github.com/LearnBoost/mongoose/issues/1381 has been closed 7 months ago with the following solution as a workaround. I had to change it slightly to merge the populated subdocument back to the main document.
The subdocument's model Story has to be specified explicitly:
Person.findById(user1._id).populate("stories")
.exec(function(err, doc {
Story.populate(doc.stories, {path: 'creator'}, function (err, stories) {
doc.stories = stories;
return doc;
})
})
In the solution above this works:
Story.populate(doc.stories, {path: 'creator'}, callback)
but this still won't work:
Story.populate(doc, {path: 'stories.creator'}, callback)
Follow-up on #JohnnyHK's post, you can specify the Model to use in populate() for now:
https://github.com/LearnBoost/mongoose/issues/1377#issuecomment-15920370
I had several nest layers deep of sub docs, and none of the supplied options worked for me. I found this amazing Mongoose plugin that will do deep population seamlessly. You just use the same syntax you would expect to work with populate, but it actually works.
https://github.com/buunguyen/mongoose-deep-populate
I have something that looks a slightly different but populates the document with the array items. I'm wondering if it's the objectid's that are causing the issues.
var mongoose = require('mongoose');
var Schema = mongoose.Schema, ObjectID = Schema.ObjectId;
var SubSchema = new Schema({
testsub: String,
created: { type: Date, default: Date.now }
});
var MainSchema = new Schema({
test: String
subs: [SubSchema],
created: { type: Date, default: Date.now }
});
mongoose.model('MainSchema', MainSchema, mainschema);
var query = MainSchema.find({});