Description
Prerequisites
- I have written a descriptive issue titleI have searched existing issues to ensure the bug has not already been reported
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
Activity
IslandRhythms commentedon Jul 22, 2022
It doesn't throw an error, but it doesn't do its job either
chaeron commentedon Jul 23, 2022
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.
vkarpov15 commentedon Jul 27, 2022
@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
strictQuery: false
on both base schema and discriminator schema. Below script works as expected: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
await Event.find({ url: 'google.com'}, {strictQuery: false})
, you should doawait Event.find({ url: 'google.com'}, null, {strictQuery: false})
, orawait Event.find({ url: 'google.com'}).setOptions({strictQuery: false})
. 2nd arg tofind()
is projection, not options.[-]Query on Base model of discriminator throws away query parameters not in base schema[/-][+]Discriminator schema should inherit base schema options[/+]oonsamyi commentedon Aug 11, 2022
@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 :(
oonsamyi commentedon Aug 11, 2022
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:
vkarpov15 commentedon Sep 2, 2022
If you did
mongoose.set('strictQuery', 'throw')
, that works. You don't need to set 'strictQuery' on every schema.fix: correctly handle defaulting discriminator schema options to base…
more coverage for #12135
docs: add discriminator schema option changes to migration guide
vkarpov15 commentedon Feb 4, 2023
Fixed by #12928