I Have following model for a team
var team = new mongoose.Schema({
supervisor: { type: mongoose.Schema.Types.ObjectId, ref: 'employee' }, // SupervisorId
commanders: [{
employee: { type: mongoose.Schema.Types.ObjectId, ref: 'employee' }, //under supervisor
level: { type: Number, defult: 1 }
}]
});
while fetching data from DB I am able to populate supervisor but not employees in commanders array
I tried something like below
db.team.findOne({
supervisor: employeeId
}).populate({
path: 'supervisor',
populate: {
path: 'commanders',
populate: {
path: 'employee',
model
}
}
})
Need help.!!
Try with This:
db.team.findOne({
supervisor: employeeId
}).populate('supervisor commanders.employee')
Related
In my blog model;
...
user: {
type: mongoose.Types.ObjectId,
ref: 'users',
required: true,
},
...
And this is my user model;
follower: [
{
type: mongoose.Types.ObjectId,
ref: 'users'
}
],
So I'm gettting data like this;
const Post = await Blog.findOne({slug: post}).populate({
path: 'user',
select: 'name image count(follower)'
})
Of course count(follower) not working. I want to get followers count, how can I do that?
I want to populate the fields of a subdocument, which is a discriminated element of a common Schema (Notificationable discriminated into Message or FriendRequest).
This question is quite similar to this one: mongoosejs: populating an array of objectId's from different schemas, which was not solved two years ago. Since mongoose evolved, and discriminator also, I am asking the question again.
What I have tried so far:
Notification.find({_id: 'whatever'})
.populate({
path: 'payload',
match: {type: 'Message'},
populate: ['author', 'messageThread']
})
.populate({
path: 'payload',
match: {type: 'FriendRequest'},
populate: ['to', 'from']
})
.exec();
This does not work, because the path is the same.
So I tried:
Notification.find({_id: 'whatever'})
.populate({
path: 'payload',
populate: [
{
path: 'messageThread',
match: {type: 'Message'},
},
{
path: 'author',
match: {type: 'Message'},
},
{
path: 'from',
match: {type: 'FriendRequest'},
},
{
path: 'to',
match: {type: 'FriendRequest'},
},
]
})
.exec();
Which does not work either, maybe because the match is executed in the subdocument and thus does not have a field type.
Is there any solution for this?
Here are my (main) models, I did not provide User or MessageThread.
The main document:
const NotificationSchema = new Schema({
title: String,
payload: {
type: Schema.Types.ObjectId,
ref: 'Notificationable'
});
mongoose.model('Notification', NotificationSchema);
The payload Parent schema
let NotificationableSchema = new Schema(
{},
{discriminatorKey: 'type', timestamps: true}
);
mongoose.model('Notificationable', NotificationableSchema);
And the two discriminated possibilities:
let Message = new Schema({
author: {
type: Schema.Types.ObjectId,
ref: 'User'
},
messageThread: {
type: Schema.Types.ObjectId,
ref: 'MessageThread'
}
}
Notificationable.discriminator('Message', Message);
And:
let FriendRequest = new Schema({
from: {
type: Schema.Types.ObjectId,
ref: 'User'
},
to: {
type: Schema.Types.ObjectId,
ref: 'User'
}
}
Notificationable.discriminator('FriendRequest', FriendRequest);
This is the relevant portion of my Schema:
var classroomSchema = mongoose.Schema({
students: [{
_id: mongoose.Schema.Types.ObjectId,
ref: 'User',
rate: {
type: Number,
default: 200,
},
referrals: [mongoose.Schema.Types.ObjectId],
}],
)};
Here rate and referrals are properties of the students which are valid in the context of that classroom, and cannot be populated from the Students model.
Is there any way to define my schema such that I can keep those fields(rate and referrals) and also use populate to link other fields such as name, age, etc of the student?
Change your schema to this:
var classroomSchema = mongoose.Schema({
students: [{
rate: { type: Number, default: 200 },
user: { ref: 'User', type: Schema.Types.ObjectId },
referrals: [mongoose.Schema.Types.ObjectId],
}],
});
Usage:
classroom
.findOne(...)
.populate('user')
.exec((err, classroom) => {
let student0 = classroom.students[0];
// student0.rate
// student0.user.name
});
I have the following schemas:
var userSchema = new Schema({
username: String,
rooms: [{type: Schema.Types.ObjectId, ref: 'Room'}]
});
var roomSchema = new Schema({
members: [
{
user:{type:Schema.Types.ObjectId, ref 'User'},
role: String
}
],
messages: [
{
text: String,
meta: {
send: {type: Schema.Types.ObjectId, ref 'User'},
sent_time: Date
}
}
]
});
I wish to obtain all rooms of a particular user and deep populate each room to get populated messages and members arrays so that each sender in a message is populated with username and each member is populated with his/her username, something like this:
User.findById(id).
populate({
path: 'rooms',
populate: [
{
path: 'members.user',
select: 'username'
},
{
path: 'messages.meta.sender',
select: 'username'
}
]
}).exec(function(err, self) { // self becomes deep populated});
Obviously, the above didn't work for me.
I have the following mongoose schema structure
userSchema = new Schema({
roles: [
role: {type: Schema.Types.ObjectId, ref: 'Role' }
]
})
rolesSchema = new Schema({
name: String,
roleEntities: [
{
entity : {type: Schema.Types.ObjectId, ref: 'RoleEntity' },
abilities : [{type: Schema.Types.ObjectId, ref: 'Ability' }]
}
]
}
roleEntitiesSchema = new Schema({
name: String
})
abilitiesSchema = new Schema({
name: String
})
How can i populate all these nested documents while doing a find on the USER model?
I tried using populate as below
User.find(ctx.request.query).populate(
{path: 'roles.role'
,populate: { path: 'roleEntities.entity'}
}).
exec()
but it's not resolving roleEntities.entity
Here's an extreme example of a deep populate nested inside of multiple objects/arrays:
Deal.find()
.populate({
path: 'fund',
populate: [{
path: 'organizer',
populate: {
path: 'banking.accounts.transactions.associatedInvestment',
model: 'Investment'
}
}, {
path: 'documents'
}]
})
You can try chaining populate operations
User.find()
.populate("roles.role")
.populate("roles.role.roleEntities.entity")
Mongoose 4 :
User
.find()
.populate({
path: 'roleIds',
model: 'roles',
populate: {
path: 'otherIds',
model: 'other'
}
})
for me worked the following
.populate({
path: 'favorites.favorite',
model: 'Joke',
populate: {
path: 'user',
model: 'User',
},