Comments (34)
I think this is the most elegant solution :
Create your parent model as usual
imports: [
MongooseModule.forFeature([{ name: ANIMAL_MODEL_NAME, schema: AnimalSchema }]),
],
To create a child model
providers: [
{
provide: getModelToken(CAT_MODEL_NAME),
useFactory: (animalModel) =>
animalModel.discriminator(CAT_MODEL_NAME, CatSchema),
inject: [getModelToken(ANIMAL_MODEL_NAME)]
}
],
@kamilmysliwiec Thank you so much !! great architecture !
from mongoose.
@kamilmysliwiec how discriminators are used with this library? it's possible?
from mongoose.
Hey,
Finally I've could managed to solve the issue. The discrimination rules must be added in the service constructor after the model injected because in the schema file it didn't worked. You can close this issue since has a workaround.
Thanks for your great library!
from mongoose.
It would be great if you can share your solution with other people so they could use it as a reference :)
from mongoose.
I made it work without need for using same provider in multiple modules
But thank you
It will be maybe useful sometimes @Crackz
from mongoose.
I made it work without need for using same provider in multiple modules
But thank you
It will be maybe useful sometimes @Crackz
How? Im facing same issue...
from mongoose.
@Crackz thanks for the example. I wanted to ask how i can do it using nestjs/mongoose style, i.e using class with decorator etc.. Can you please show me an example on how to do that using class with decorator style? thanks
from mongoose.
@WarKaa Sorry, it was deleted.
you could take a looks on
https://github.com/nestjs/mongoose/blob/master/tests/e2e/discriminator.spec.ts
or my other repo which using discriminators
https://github.com/taisiusyut/taisiusyut/tree/master/packages/server/src/modules/user/schemas
from mongoose.
I'd recommend using the nest mongoose way that you mentioned
you can find my example here It's for the ones who aren't comfortable with nest mongoose abstracting their schemas
from mongoose.
For me the discriminators array is undefined in the service.
from mongoose.
I have a workaround. In the service constructor I could add the discriminators and it works, but not with save method during creation, only the this.model.create(... save works for update only. However would be nice to handle it in module after providers are imported.
from mongoose.
Honestly, I don't understand the problem. Discriminators can be used in the same way as in the normal, pure mongoose app.
from mongoose.
@ssi-hu-tasi-norbert can you share an example please?
from mongoose.
https://github.com/norbert-tasi/nestjs-mongoose
pls look for question.schema for discriminators. question.service does the trick.
I hope it helps you!
from mongoose.
@Crackz and how do you use it in some service?
how do you inject that child model?
with @InjectModel(CAT_MODEL_NAME) catModel: Model<CatSchema>
??
Because I tried it like this, and it didn't work
So, can you explain me how do you do some query on that specific child model?
from mongoose.
@Crackz and also, what if you need same child model in 2 different modules?
i tried to define them in 2 different modules, and was not able to do it, error was that specific model can't be defined twice
from mongoose.
@ssi-hu-tasi-norbert but looking at that example, how can you know does it return you a model for email or range or datebox?
for example i want to query only for questions that are emails, and i want it to return me some Document
that is generated for example from EmailSchema
?
lets say i have created some type-safe document out of this schema and want to type output of some query to this document
from mongoose.
You set the discriminatorKey to whatever you want. In my example: discriminatorKey: 'kind'
The kind is a field/attribute just like others. You can query it.
from mongoose.
I am sorry @Crackz , I made a mistake
this solution is working really nice.
I made a mistake because i use {}
around this discriminator
call, so i missed return
inside of it
only problem with this is, if you need same model in 2 different modules, because you can't initialize it twice
but thanks for help
from mongoose.
Hi, @NenadJovicic
i have not tested your given case because i use repository pattern. anyway i'd suggest you to export your child model which is one of the providers ! so any other module would import it . you will be able to @InjectModel(CHILD_MODEL_NAME) into it !
from mongoose.
I think this is the most elegant solution :
Create your parent model as usual
imports: [ MongooseModule.forFeature([{ name: ANIMAL_MODEL_NAME, schema: AnimalSchema }]), ],
To create a child model
providers: [ { provide: getModelToken(CAT_MODEL_NAME), useFactory: (animalModel) => animalModel.discriminator(CAT_MODEL_NAME, CatSchema), inject: [getModelToken(ANIMAL_MODEL_NAME)] } ],
Hi @Crackz, I'm sorry, I am a little bit lost on how to initialize or inject the model of animalModel
in the provider here:
useFactory: (animalModel) =>
Could you kindly explain how to get it? 🙏
from mongoose.
To use it in some service that is in same module, it is easy
Because you just do standard NestJS
constructor(@InjectModel(CAT_MODEL_NAME) private catModel: Model<CatDocument>)
I only don't know how to use this same model in different module
@ksugiarto
from mongoose.
@Crackz I also separate logic by modules, but had some case where I had to use same model in 2 different modules, and this solution was not working
from mongoose.
@NenadJovicic i made a fully working example. i hope you find it useful
https://github.com/Crackz/nest-mongoose-discriminator-test
from mongoose.
Hey,
Finally I've could managed to solve the issue. The discrimination rules must be added in the service constructor after the model injected because in the schema file it didn't worked. You can close this issue since has a workaround.
Thanks for your great library!
can you send a example please
from mongoose.
hi, i need to both define the discriminator AND use hooks (pre, post). So if i define the discriminator in a provider like the example of @Crackz , where can i then define the hooks (in other examples i see hooks are defined in the MoongooseModule.forFeatureAsync factory). Please advise.
from mongoose.
@vtrphan
If you take a look at this example
you'd have a traditional mongoose schema so you can do it like this :
import { Schema } from 'mongoose';
const CatSchema: Schema = new Schema(
{
bad: {
type: Boolean,
default: false
}
},
{ discriminatorKey: 'type' }
);
CatSchema.pre('save', function (next) {
console.log('meow!!!!!!!!');
});
export { CatSchema };
from mongoose.
@Crackz any idea how i can use mongoose hooks and discriminator with nestjs/mongoose style (class with decorators) instead of traditional mongoose schema? Thanks
from mongoose.
@vtrphan sorry, I know nothing about nestjs/mongoose decorators because i think it's unnecessary level of abstraction.
i'd recommend you creating a new issue asking @kamilmysliwiec
from mongoose.
Hi @Crackz i tried your solution but im getting an error
Cannot overwrite Processor model once compiled. at Function.Model.discriminator (/home/john/Documents/Projects/pchubbuilder/node_modules/mongoose/lib/model.js:1125:11)
i just provided the provider and i got this error.
This is my code
@Module({
imports: [
MongooseModule.forFeature([
PCBUILD_FEATURE,
PART_FEATURE,
NOTIFICATION_POOL_FEATURE,
USER_FEATURE,
PROCESSOR_FEATURE,
]),
],
controllers: [PcBuildController],
providers: [
PcBuildService,
{
provide: getModelToken('Processor'),
useFactory: partModel =>
partModel.discriminator('Processor', ProcessorSchema),
inject: [getModelToken(PART_FEATURE.name)],
},
],
})
export class PcBuildModule {}
Do you know what is this error? Thanks!
from mongoose.
@johnfrades Sorry For The Late Reply
i'd move PART_FEATURE to its own module and just import it into the child module
check animal module in the example
from mongoose.
@vtrphan Here is an example for single-nested-discriminators.
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Circle, CircleSchema } from './circle.schema';
import { Square, SquareSchema } from './square.schema';
@Schema({ discriminatorKey: 'kind' })
export class Shape {
@Prop({ type: String, required: true })
kind: string;
}
export const ShapeSchema = SchemaFactory.createForClass(Shape);
@Schema()
export class ShapeTest {
@Prop({ type: ShapeSchema, required: true })
shape: Shape;
}
export const ShapeTestSchema = SchemaFactory.createForClass(ShapeTest);
ShapeTestSchema.path('shape').discriminator(Circle.name, CircleSchema);
ShapeTestSchema.path('shape').discriminator(Square.name, SquareSchema);
You may also need the type definition, @types/mongoose
is not supported yet ( related issue ). Remember to set skipLibCheck
to false
in tsconfig.json
declare module 'mongoose' {
class SchemaType {
discriminator<U extends Document>(name: string, schema: Schema): Model<U>;
}
}
from mongoose.
Hey @Pong420, is your repo still available ?
from mongoose.
I think this is the most elegant solution :
Create your parent model as usual
imports: [ MongooseModule.forFeature([{ name: ANIMAL_MODEL_NAME, schema: AnimalSchema }]), ],
To create a child model
providers: [ { provide: getModelToken(CAT_MODEL_NAME), useFactory: (animalModel) => animalModel.discriminator(CAT_MODEL_NAME, CatSchema), inject: [getModelToken(ANIMAL_MODEL_NAME)] } ],
@kamilmysliwiec Thank you so much !! great architecture !
please share more info. if it is possible please create a repo for your solution
and as a extra information for others: in nestjs DOC there is a very simple and good way to deal with discriminators.
from mongoose.
Related Issues (20)
- Typescript 5 @InjectModel HOT 2
- Subdocuments Array has not id() and remove()-method HOT 3
- Don't extend `MongooseModuleOptions` from `Record<string, any>` HOT 4
- Using getters and setters with in super class HOT 1
- Issue with RXJS dependency (0 , rxjs_1.lastValueFrom) is not a function HOT 1
- How do I integrate @casl/mongoose and how do I operate to modify the Model? HOT 1
- How do I integrate @casl/mongoose, it doesn't seem to compile through. HOT 1
- NestJS: Mongo one to many relationship doesn't work HOT 1
- cache connection HOT 1
- Support compound index in @Schema decorator HOT 1
- Unexpected ref function behaviour HOT 1
- OverwriteModelError: Cannot overwrite `X` model once compiled. HOT 2
- @Prop() schemaType on Map not working HOT 3
- findOneAndUpdate fails with multi arrayFilters in nested arrays HOT 1
- Unable to connect for non-SSL connections when specifying dbName in URI HOT 1
- Update mongoose to v8 HOT 2
- InjectModel decorator for multiple databases is broken since version 9.1.0 HOT 1
- When set connectionName to useClass, Populate Error: Schema hasn't been registered for model HOT 1
- Injecting services into MongooseModule.forFeatureAsync not triggering the middleware hooks HOT 1
- @Prop() schemaType on Map not working.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mongoose.