-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Discriminator schema should inherit base schema options #12135
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
Comments
It doesn't throw an error, but it doesn't do its job either const mongoose = require('mongoose');
const assert = require('assert');
const options = { discriminatorKey: 'kind' };
const eventSchema = new mongoose.Schema({ time: Date }, options);
const Event = mongoose.model('Event', eventSchema);
// ClickedLinkEvent is a special type of Event that has
// a URL.
const ClickedLinkEvent = Event.discriminator('ClickedLink',
new mongoose.Schema({ url: String }, options));
async function run() {
await mongoose.connect('mongodb://localhost:27017');
await mongoose.connection.dropDatabase();
// When you create a generic event, it can't have a URL field...
const genericEvent = await Event.create({ time: Date.now(), url: 'google.com' });
assert.ok(!genericEvent.url);
await Event.create({url: 'test'})
// But a ClickedLinkEvent can
const clickedEvent = await ClickedLinkEvent.create({ time: Date.now(), url: 'google.com' });
await ClickedLinkEvent.create({ url: 'clicked test'})
assert.ok(clickedEvent.url);
const test = await Event.find({ url: 'google.com'}, {strictQuery: false})
console.log(test);
}
run(); |
It doesn't throw an error, because I believe strictQuery is a schema option, not a query one, per the documentation: https://mongoosejs.com/docs/guide.html#strictQuery If you specify the schema option on eventSchema in your example, I believe it will throw an error when you try to run. |
@chaeron when you say "OK...maybe this is the expected behaviour, so I tried to set strictQuery: false on the base Event schema. But then Mongoose throws an error saying this is not allowed.", I think the issue you're seeing is that you need to set
For 7.0, we should consider making discriminator schemas inherit the base schema's options by default, rather than requiring people to explicitly specify the exact same options. Side note: @IslandRhythms the issue with your script is that you're doing |
@vkarpov15 What if I already have option strictQuery: 'throw' for all app?
What is workaround in that case? I don't want change behavior for discriminator schemas via strictQuery: false :( |
I found workaround for my case: define all fields that will be searched by on base schema with optional property. I use nest.js with mongoose and my solution looks like: @Schema({ discriminatorKey: 'type' })
export class BaseLog {
@Prop({
type: String,
required: true,
enum: LogType,
index: true,
})
type: LogType
@Prop({ required: true, index: true })
userId: number
// field that exist in CreateCabinetLog only and will be searched by: Log.find({ cabinetId })
@Prop({ sparse: true })
cabinetId?: number
}
export class CreateCabinetLog {
type: LogType.createCabinet
userId: number
// specify field as type, without Prop decorator
cabinetId: number
// field that exist in CreateCabinetLog only and will not be searched by
@Prop({ required: true })
name: string
}
export const BaseLogSchema = SchemaFactory.createForClass(BaseLog)
export const CreateCabinetLogSchema = SchemaFactory.createForClass(CreateCabinetLog) |
If you did |
Fixed by #12928 |
Prerequisites
Mongoose version
6.4.6
Node.js version
16.x
MongoDB server version
6.0
Description
We use discriminators a lot, and have multiple discriminator models built on a base model/schema.
Tried to do a query against the base model, using fields in some of the discriminator schemas, but Mongoose seems to strip out the query fields that are not found in the base model, even though they are in the discriminator models/schemas.
For the Event example found here: https://mongoosejs.com/docs/discriminators.html, this would be doing a query as follows
let events = Event.find( { url: "some value" } );
where url is only specified in the ClickedLinkEvent discriminator schema, not in the base Event schema.
If you do this, you get all events back, since the url field is removed and the query becomes just {}.
OK...maybe this is the expected behaviour, so I tried to set strictQuery: false on the base Event schema. But then Mongoose throws an error saying this is not allowed.
I believe we should be able to specify strictQuery: false on a base schema/discriminator and have it not strip out any fields that are not in the base schema. That would resolve our issue.
The workaround for this was to just get the db connection and do a query using the MongoDB driver directly on the discriminated collection, but we shouldn't have to do this, since a query like this using Mongoose does not return expected results.
Steps to Reproduce
See description
Expected Behavior
No response
The text was updated successfully, but these errors were encountered: