ITADN

strictQuery` passed as a query option is ignored when casting `arrayFilters

#16447Closedvrana055 创建于 19 天前
V
vrana055commented
### 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 条评论