strictQuery` passed as a query option is ignored when casting `arrayFilters
### Prerequisites
- [x] I have written a descriptive issue title
- [x] I have searched existing issues to ensure the bug has not already been reported
### Mongoose version
9.9.1
### Node.js version
26.7.0
### MongoDB server version
7.0.18
### Typescript version (if applicable)
_No response_
### Description
strictQuery is respected for array filters when set on the schema or globally, and query-level strict is respected too, but query-level strictQuery is silently ignored. Passing it to updateOne() or setOptions() still throws Could not find path ... in schema.
lib/helpers/update/castArrayFilters.js reads query._mongooseOptions.strictQuery, but nothing assigns that key for a normal query — setOptions() copies options into _mongooseOptions by explicit name and strictQuery isn't among them, while strict is (lib/query.js:4559). Filter casting reads query.options.strictQuery instead (lib/cast.js:423, fed by lib/query.js:5224), which is why the same option works there.
Related: #11062 fixed query-level strict for array filters, #11836 fixed the global strictQuery flag. Query-level strictQuery looks like the remaining case.
### Steps to Reproduce
```
'use strict';
const mongoose = require('mongoose');
const itemSchema = new mongoose.Schema({ name: String }, { _id: false });
const update = { $set: { 'items.$[item].name': 'updated' } };
const arrayFilters = [{ 'item._id': 'item-1' }];
async function seed() {
const coll = mongoose.connection.collection('things');
await coll.deleteMany({});
// Inserted with the driver: `_id: false` means Mongoose would strip these _ids.
await coll.insertOne({
tag: 't',
items: [{ _id: 'item-1', name: 'original' }, { _id: 'item-2', name: 'keep' }]
});
}
async function attempt(label, model, options) {
await seed();
try {
const res = await model.updateOne({ tag: 't' }, update, options);
console.log(label.padEnd(32), 'OK modifiedCount=' + res.modifiedCount);
} catch (err) {
console.log(label.padEnd(32), 'THROW ' + err.message);
}
}
async function main() {
await mongoose.connect('mongodb://127.0.0.1:27017/test');
const fields = { tag: String, items: [itemSchema] };
const Loose = mongoose.model('Loose', new mongoose.Schema(fields, { strictQuery: false }), 'things');
const Default = mongoose.model('Default', new mongoose.Schema(fields), 'things');
await attempt('schema { strictQuery: false }', Loose, { arrayFilters });
await attempt('query { strict: false }', Default, { arrayFilters, strict: false });
await attempt('query { strictQuery: false }', Default, { arrayFilters, strictQuery: false });
await seed();
try {
const res = await Default.updateOne({ tag: 't' }, update, { arrayFilters })
.setOptions({ strictQuery: false });
console.log('setOptions({ strictQuery: false })', 'OK modifiedCount=' + res.modifiedCount);
} catch (err) {
console.log('setOptions({ strictQuery: false })', 'THROW ' + err.message);
}
await mongoose.disconnect();
}
main();
```
Output on 9.9.1:
schema { strictQuery: false } OK modifiedCount=1
query { strict: false } OK modifiedCount=1
query { strictQuery: false } THROW Could not find path "items.0._id" in schema
setOptions({ strictQuery: false }) THROW Could not find path "items.0._id" in schema
### Expected Behavior
The last two lines should behave like the first two — OK modifiedCount=1. Query-level strictQuery should override the schema and global settings for array filters, the same way query-level strict already does and the same way strictQuery already does for query filters.
关闭于 9 天前 0 条评论