Find on nested discriminators is broken after upgrade from mongoose 5 to mongoose 6
See original GitHub issuePrerequisites
- I have written a descriptive issue title
- I have searched existing issues to ensure the bug has not already been reported
Mongoose version
6.5.2
Node.js version
16.15.0
MongoDB server version
4.4
Description
We are currently migrating from mongoose 5 to mongoose 6, and it seems like nested discriminators are broken with mongoose 6. When we find
by a nested discriminated field, the query will return all documents instead of matching ones. This has created quite a few bugs for us while testing our code with mongoose 6, where completely unrelated data is being returned from queries. The culprit seems to be the new strictQuery
option, and setting it to false
patches the issue. However, having to set this option for nested fields seems like a broken behavior to use.
Steps to Reproduce
The following script shows the error. The find call should return only the second document. However, both are returned.
import mongoose from 'mongoose';
const BaseDocumentSourceSchema = new mongoose.Schema({
source: { type: String },
}, {
discriminatorKey: 'type'
});
const InternalDocumentSchema = new mongoose.Schema({
source: { type: String },
});
const ExternalDocumentSchema = new mongoose.Schema({
source: { type: String },
url: { type: String },
});
const DocumentSchema = new mongoose.Schema({
source: BaseDocumentSourceSchema,
});
DocumentSchema.path('source').discriminator('internal', InternalDocumentSchema);
DocumentSchema.path('source').discriminator('external', ExternalDocumentSchema);
const DocumentModel = mongoose.model('Document', DocumentSchema);
(async () => {
await mongoose.connect(`mongodb://localTestUser:HhPQ5rEUvbDgqrkE3c@localhost:27017/frankhr_test`);
await mongoose.connection.db.dropDatabase();
const doc1 = await DocumentModel.create({ source: { type: 'internal' } });
const doc2 = await DocumentModel.create({ source: { type: 'external', url: 'url' } });
console.log(doc1, doc2);
// Expected result is document 2. However, it will return both documents.
const results = await DocumentModel.find({ 'source.url': 'url' });
console.log(results);
// Query correctly returns document 2
const strictResults = await DocumentModel.find({ 'source.url': 'url' }, undefined, { strictQuery: false });
console.log(strictResults);
await mongoose.disconnect();
})();
Expected Behavior
Queries using nested discriminated fields should return the correct data.
Issue Analytics
- State:
- Created a year ago
- Comments:7 (1 by maintainers)
Top GitHub Comments
The original issue is a problem. We’re planning on changing
strictQuery
’s default value back tofalse
in 7.0: https://github.com/Automattic/mongoose/issues/11861 , which will fix the original issue. I’m sorry for the inconvenience, thestrictQuery
change in 6.0.0 turned out to be a bad design decision in hindsight.@vkarpov15 I can confirm that your script works. It seems like I didn’t set
strictQuery
for the nested schemas as I assumed the parent options would also apply to the nested child schemas.Setting
strictQuery
for the child schemas works and solves this issue: https://github.com/Automattic/mongoose/issues/12318#issuecomment-1228138014However, the original issue still exists. When
strictQuery
is not set or enabled, nested discriminated fields don’t work anymore.