How to retrive profile and user schema with mongoose in one command? - node.js

How to have user and profile together?
This is how User schema defined:
const UserSchema = new Schema({
email: { type: String, required: true },
name: { type: String, required: true },
password: { type: String },
picture: { type: String },
});
and Profile schema:
const ProfileSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: 'User' },
setting1: { type: String, enum: ['YES', 'NO', 'UNKNOWN'], default: 'UNKNOWN' },
setting2: { type: String, enum: ['YES', 'NO', 'UNKNOWN'], default: 'UNKNOWN' },
setting3: { type: String, enum: ['YES', 'NO', 'UNKNOWN'], default: 'UNKNOWN' },
});
How can I retrieve in one command/line the profile when I ask for user?
User.findOne({ email: 'blabla#gmail.com' })
I have try populate but it is not works:
User.findOne({ email: 'blabla#gmail.com' }).populate('profile')
Please notice: I don't want to have profile in user in the same schema.

You would need to link the Profile inside the UserSchema:
const UserSchema = new Schema({
profile: { type: Schema.Types.ObjectId, ref: 'Profile' },
email: { type: String, required: true },
name: { type: String, required: true },
password: { type: String },
picture: { type: String },
});

Related

populate() doesn't fetch referenced profile instead it fetches the first profile in my collection

I have three collections which are User, Profile and Userpost and all referenced accordingly. The challenge I am facing is that when I use the .populate(), instead of fetching the Profile information of the logged in user, it fetches the data of the first profile on the profile collections and it does so for any user that is logged in. Kindly help me resolve. Thanks
How I populate
router.get('/getpost/:id', (req, res) => {
const id = req.params.id;
Userpost.find({User:id}).populate('Profile').populate('User', {password: 0}).exec((err,docs) => {
if(err) throw(err);
res.json(docs);
})
});
UserpostSchema
const UserpostSchema = new Schema({
post: {
type: String,
required: true
},
User: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
required: true,
},
Profile: {
type: mongoose.Schema.Types.ObjectId,
ref: 'profile',
required: true,
}
});
const Userpost = mongoose.model('userpost', UserpostSchema);
module.exports = Userpost;
Profile
const ProfileSchema = new Schema({
lastname: {
type: String,
required: true,
},
firstname: {
type: String,
required: true,
},
othernames: {
type: String,
required: true,
},
countries: {
type: String,
required: true,
},
phones: {
type: String,
required: true,
},
User: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
required: true,
},
});
const Profile = mongoose.model('profile', ProfileSchema);
module.exports = Profile;
and User
const userSchema = new Schema({
username: {
type: String,
required: true
},
roles: {
User: {
type: Number,
default: 2001
},
Mentor: Number,
Admin: Number
},
password: {
type: String,
required: true
},
userID: {
type: String,
required: true
},
refreshToken: String
});
const User = mongoose.model('user', userSchema);
module.exports = User;

I want to join two schemas into one schema in nodejs mongodb

I want to join two schemas into one because they both have almost same attributes and i want to use it for PostSchema that a user and also an owner can create and show their posts but i dont know how to achieve it
for example :
UserSchema
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
gender: String,
role: {
type: String,
default: "User",
},
});
OwnerSchema
const OwnerSchema = new mongoose.Schema({
name: String,
gender: String,
email: String,
password: String,
role: {
type: String,
default: 'Owner'
},
restaurant: RestaurantSchema
})
PostSchema
const PostSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
body: {
type: String,
required: true,
},
photo: {
type: String,
required: true,
},
postedBy: {
type: ObjectId,
ref: *Combined user and owner*,
},
comments: [CommentSchema],
}, { timestamps: true });
Get rid of your OwnerSchema - and modify your UserSchema to something like the below:
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
gender: String,
role: {
type: String,
default: "User", //could be Owner when applicable
},
restaurant: RestaurantSchema, //could be null when role=User
});

Mongoose schema with field of an array of other schemas

first of all, I am a beginner and currently, I am working on a social media blog type.
Now, I have my userSchema and postSchema models:
USER MODEL
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Please insert your name'],
},
email: {
type: String,
required: [true, 'Please insert your email'],
unique: true,
lowercase: true, //transform into lowercase / not validator
validate: [validator.isEmail, 'Please provide a valid email'],
},
avatar: {
type: String,
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user',
},
password: {
type: String,
required: [true, 'Please provide a password'],
minLength: 8,
select: false,
},
passwordConfirm: {
type: String,
required: [true, 'Please confirm your password'],
validate: {
validator: function (el) {
return el === this.password;
},
message: 'Passwords are not the same',
},
},
passwordChangedAt: Date,
posts: [] // ???????????????
});
POST MODEL
const postSchema = new mongoose.Schema({
title: {
type: String,
required: [true, 'A post must have a title'],
},
author: {
type: String,
required: [true, 'A post must have a title'],
},
likes: {
type: Number,
default: 10,
},
comments: {
type: [String],
},
image: {
type: String,
},
postBody: {
type: String,
required: [true, 'A post must contain a body'],
},
createdAt: {
type: Date,
default: Date.now(),
select: false,
},
});
Now I don't know if it's the best approach but I was thinking of having a field in userSchema with the type of an array of postSchema so I will have for each user their own posts created. Can I do that? If not how I can achieve that?
Should I use search params fields to filter posts by the author? I am really confused how I should approach this situation. Thank you guys
Check out this example
const UserSchema = new mongoose.Schema({
username: String,
posts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}]
})
const PostSchema = new mongoose.Schema({
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
})
const Post = mongoose.model('Post', PostSchema, 'posts');
const User = mongoose.model('User', UserSchema, 'users');
module.exports = { User, Post };
Credit: https://medium.com/#nicknauert/mongooses-model-populate-b844ae6d1ee7

Populate() specify multiple model

I'm looking to make a populate() on a find() request but specifying multiple models, so if no occurrence is found on the first specified model the population will make on the second.
Here is an example of what I would like to do :
const userSch = new Schema({
username: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
mail: {
type: String,
required: true,
unique: true,
}
});
const botSch = new Schema({
username: {
type: String,
required: true,
},
token: {
type: String,
required: true,
unique: true,
},
owner: mongoose.Schema.Types.ObjectId
});
const nspSch = new Schema({
name: String,
channels: [channels],
users: [{
id: {
type: mongoose.Schema.Types.ObjectId,
},
bot: {
type: Boolean,
}
}],
});
const channels = new Schema({
name: String,
message: [{
user: {
type: Schema.Types.ObjectId,
},
content: String,
}],
});
const nsp = mongoose.model('namespace', nspSch);
const Auth = mongoose.model('users', userSch);
const BotAuth = mongoose.model('bots', botSch);
function returnMs(nspID, channelID, callback) {
nsp.findOne({'_id': nspID}).populate({
path: 'channels.message.user',
model: 'users' || 'bots',
select: '_id username',
})
.exec(function(err, r) {
...
})
}
If there is ever an npm package, or a solution or even a track to code it, please share it.
Thank you

nested ref to populate mongoose 5.0 nodejs

I have two models. The first one is UserSchema and the second one is CategorySchema
var UserSchema = Schema({
firstName: {
type: String,
required: true
},
secondName: String,
lastName: {
type: String,
required: true
},
email: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
status: {
type: String,
required: true
},
roles: [{
type: Schema.ObjectId,
ref: 'Role'
}],
publications: [{
title: {
type: String,
},
description: String,
status: {
type: String,
},
createdAt: {
type: Date
},
updatedAt: {
type: Date,
default: Date.now()
},
pictures: [{
name: String
}],
categories: [{
type: Schema.Types.ObjectId,
ref: 'Category'
}],...
the model category is
var CategorySchema = Schema({
name: String,
subcategories: [{
name: String
}]
});
UserSchema has publications. Publications contains an array. Within of publications is categories that contains an array of id of subcategory(subcategory is whithin of CategorySchema)
the problem is when I need to populate categories of UserSchema. Categories of UserSchema have an array of _id of subcategory that belongs to CategorySchema.

Resources