var modelSchema = new mongoose.Schema({
name: {
type: String
},
personas: [typeA | typeB] // need one of two types here(typeA schema,typeB schema)
});
var bigSchema = new mongoose.Schema({
title: {
type: String
},
model: modelSchema
})
You have to use a Mixed
type: http://mongoosejs.com/docs/schematypes.html
Note: you will have to call doc.markModified()
on the fields that you change if you go down this route.
Mixed type allows anything (without validating). As typeA and typeB are schemas and i want to validate them.
We can do this for normal schema using discriminators or "mongoose-schema-extend". But at subdocument level i didn't found any solution.
Yeah I don't think what you're asking for in terms of specifying a type like typeA | typeB
is possible unless you compose your own custom schema for the subdocument or you used a Mixed
type.
= 4.8.0 supports this:
var eventSchema = new Schema({ message: String },
{ discriminatorKey: 'kind', _id: false });
var batchSchema = new Schema({ events: [eventSchema] });
batchSchema.path('events').discriminator('Clicked', new Schema({
element: String
}, { _id: false }));
batchSchema.path('events').discriminator('Purchased', new Schema({
product: String
}, { _id: false }));
var MyModel = db.model('gh2723', batchSchema);
var doc = {
events: [
{ kind: 'Clicked', element: 'Test' },
{ kind: 'Purchased', product: 'Test2' }
]
};
MyModel.create(doc).
then(function(doc) {
// doc.events[0] has an 'element' property, doc.events[1] has a 'product' property
});
Most use cases of this, can actually be simplified using multiple properties. For example, instead of
personas: [typeA | typeB]
```
you could do
personasTypeA: [typeA],
personasTypeB: [typeB]
```
In my case, it was files
and folders
(instead of having a flattened array of mixed file/folder, just separated them and I've let folders be recursive)
@vkarpov15 will discrimantors work with a typed field such as in the following schema?
const TypesSchema = new Schema({
type: {type:Number,enum:Object.values(constants.TYPES)}
},{descriminatorKey:'type',_id:false});
I want to have a field called type with with types defined by the constants objects, and this field will be used to descriminate among the types schemas. each type
has its own schema
@r3wt I believe so. However, you should use type: String
, because type: Number
doesn't support enum
@vkarpov15 i can't use String
, because the constant values are int and strict equality is used everywhere. I just removed the enum for now
@r3wt we'll have enum
for numbers in 5.8.0, see #8139
@r3wt we'll have
enum
for numbers in 5.8.0, see #8139
I appreciate it, but there was no way around it so we we ended up migrating all codebase to String
and it is working without any issue now. I am glad to see this feature though, now i can save disk space by using more numeric enums for hardcoded values
= 4.8.0 supports this:
var eventSchema = new Schema({ message: String }, { discriminatorKey: 'kind', _id: false }); var batchSchema = new Schema({ events: [eventSchema] }); batchSchema.path('events').discriminator('Clicked', new Schema({ element: String }, { _id: false })); batchSchema.path('events').discriminator('Purchased', new Schema({ product: String }, { _id: false })); var MyModel = db.model('gh2723', batchSchema); var doc = { events: [ { kind: 'Clicked', element: 'Test' }, { kind: 'Purchased', product: 'Test2' } ] }; MyModel.create(doc). then(function(doc) { // doc.events[0] has an 'element' property, doc.events[1] has a 'product' property });
Hey @vkarpov15, I can't call discriminator method on schema, I need to create the model first but your example above shows otherwise. Can you please clarify?
@bbhopesh Yes, you right Schema does have method discriminator, but
batchSchema.path('events') returns not a Schema, it method actually returns Schema | DocumentArrayPath. But @types/mongoose does not have right declaration, i guess.
You can find more info here
@mkovel is correct, you can call discriminator()
on certain schema types. FWIW batchSchema.path('events')
does NOT return a schema, it returns a SchemaType
Most helpful comment