Do you want to request a feature or report a bug?
Report a bug
What is the current behavior?
Let's say I have this schema:
var CustomerSchema = new Schema({
first_name: {
type: String,
required: [true, "Please path you name"]
},
last_name: {
type: String,
required: [true, "Please path you last name"]
},
address: {
type: String,
required: [true, "Address is required"]
}
}, {
toObject: {
virtuals: true
},
toJSON: {
virtuals: true
}
});
CustomerSchema.virtual('full_name').get(function () {
return this.first_name + ' ' + this.last_name;
});
And when I'm trying to find all customers but select only full_name and address I'm getting something like this:
Customers.find({}, 'full_name address', function (err, customers) {
if (err) {
console.log(err);
} else {
console.log(customers);
}
});
Results:
[{
full_name: 'undefined undefined',
address: 'Some address'
}]
For getting correct full_name I have to specify related columns (first_name and last_name) in select.
Customers.find({}, 'first_name last_name full_name address', function (err, customers) {
if (err) {
console.log(err);
} else {
console.log(customers);
}
});
Results:
[{
first_name: 'FirstName',
last_name: 'LastName'
full_name: 'FirstName LastName',
address: 'Some address'
}]
But I don't need first_name and last_name fields.
What is the expected behavior?
When I'm selecting full_name and address I expect that it will be correct full name without specifying other not needed fields.
Please mention your node.js, mongoose and MongoDB version.
NodeJS v6.10.2
Mongoose v4.9.7
MongoDB v3.4
Technically, you do need those fields, or at least Mongoose does to construct the virtual. Think about it this way: how can Mongoose know what it should put in your virtual, other than querying the respective fields?
If you suggest that mongoose should add the values it needs to the query itself, this is more of a feature request. However, I would be careful implementing this, as it becomes inefficient if you don't use that virtual in a particular call (imagine this on a large scale). If you really don't want to add those fields in your query, you can try to query them in your virtual definition when they are not defined. However this would cause an additional round trip to the database every time you access that virtual, if I'm not mistaken.
In that regard, I think you are doing it the best possible way right now ;)
OK, thanks for suggestion @c0d0g3n
I'm working with Mongo/Mongoose just for a month so far, so I don't know a lot of tricky things yet :)
But for now I just remove not needed fields result object after request is executed. I don't know if it's good idea or not.
@fylhsq123 If I understand you correctly, you don't really care about what query is being made, but what is returned to the user? In that case you could indeed remove the properties you don't need, but you should mind javascript object behavior. (F.i. using the virtual after you deleted the respective properties still won't work.)
I think it would be safer to just copy the properties you need to another object, like so:
let toUser = {
fullName: doc.fullName
// ...
}
Good luck with your project!
Oh, yeah, right.
Thank you very much for your help, you really helped me a lot! :)
@fylhsq123 You're welcome! Don't forget to close this issue as I don't have the permission to do it for you.
Hello,
We have any update for this issue now? Or I still must perform a long list object on memory as @c0d0g3n suggestion?
Thanks a lot.
@anhvietcx no updates on this issue. You need to specify all related fields for your virtual to work correctly.
Most helpful comment
Technically, you do need those fields, or at least Mongoose does to construct the virtual. Think about it this way: how can Mongoose know what it should put in your virtual, other than querying the respective fields?
If you suggest that mongoose should add the values it needs to the query itself, this is more of a feature request. However, I would be careful implementing this, as it becomes inefficient if you don't use that virtual in a particular call (imagine this on a large scale). If you really don't want to add those fields in your query, you can try to query them in your virtual definition when they are not defined. However this would cause an additional round trip to the database every time you access that virtual, if I'm not mistaken.
In that regard, I think you are doing it the best possible way right now ;)