-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create an adapter method to handle virtual population #371
Create an adapter method to handle virtual population #371
Conversation
c32ee77
to
7e34595
Compare
as I said, I think Because, I think this library need to be "moleculer first" (so, by default use moleculer => propagate) . And if you use edge case you can enable it . ( @Freezystem I think you are in an edge case, because the documentation say this module use "one database per service pattern", and you didn't follow it ) Also, I think virtuals "objects" need to be populated too . Just, instead of doing a schema request, just map the _id from the field to the virtual . |
I understand what you mean but I disagree in a sense that people using virtuals as I do will not understand why they don't populate by default. I'm using virtuals with the full power of moleculer to call the proper action once they are populated with ids. If you look closesly in the tests, I'm only populating virtuals So in my opinion, I'm not in an "edge" case at all. I'm using the We can argue about disabling it by default but it has no downside in your case as it is short-circuiting almost immediately even if you're not using the |
And in the opposite, people using virtuals and propagate will get a crash, and won't understand why it crash if they follow the documentation . I think, only @icebob can decide . but in my opinion, And, if you want to use mongoose at the full potential (and so don't follow the base concept), this is not a problem, and you have the option to do it .
My opinion about it, is to directly populate it in the entity object . Without using populate, so we can propagate on it . So, virtuals can be used ( a field like About the rest, ok, so we didn't aggree ... so, the decision came to @icebob . Did the |
Following your feedbacks I refactored the virtual population to make it moleculer first. From now on, the default behaviour will be to map virtual fields to their To use the native mongoose virtual population workflow, you'll need to set the Feel free to check the tests to see if the implementation I made fit your usage. |
Yes In my opinion, it can be good . it allow a moleculer user to use mongoose virtuals, with "one database per service" . he just need to create the correct actions to propagate . |
I do not fully understand every part of this virtual populating but the code looks good to me. |
1ed9c3a
to
7ab6a52
Compare
PR was missing a test. It's now ready for review and merge |
const options = {skipInvalidIds: true, lean: true}; | ||
const transform = (doc) => doc._id; | ||
const populate = virtualsToPopulate.map(path => ({path, select: "_id", options, transform})); | ||
const useNativeMongooseVirtuals = _.get(ctx, "service.settings.useNativeMongooseVirtuals", false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a pointer to the service instace as this.service
. Please use it instead of ctx.service...
In addition, this property is very constant, so better if you get it in init
to a local class variable because lodash get
is not too fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed unnecessary use of _.get
, it should be ok now.
5b98ac4
to
93489da
Compare
93489da
to
d3ce10a
Compare
Handle virtual population in a dedicated method of the mongoose adapter
I've separated, in a dedicated method, the code that handles the virtuals population. It allows the code to be more readable and easier to unit test.
Also I've included some short-circuits to avoid useless overhead and keep the virtual step as fast as possible, especially when it need to be bypassed.
Now, You can also disable the virtual population mechanism by adding
{virtuals: false}
in the service settings (request made by @thib3113). Note that letting the service decide by itself is now nearly as fast as adding this option.Overridding virtual populate defaults
You can now override populate options for each virtuals separately by providing an object in the service
settings.virtuals
.example:
Remove restricted field projection in virtual populate if there is a match clause
I recently came accross an issue involving virtuals with a
match
clause.When I implemented the virtual population the first time, I intentionally limited the retrieved fields to the
_id
only to optimize memory/bandwith usage.Unfortunately it has the side effect to prevent virtual
match
clauses from filtering properly.Indeed, mongoose execute the
match
clause as a filter on the populated list but not in the populate query itself as I previously though.Thus, when the virtual has a
match
clause, we need to retrieve the whole document to allow its proper execution.I also allow the population of virtuals using the
refPath
option, which is not documented but allowed by the code. Previously only virtuals withref
option would have been populated. see code