-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Closed
Labels
confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.We've confirmed this is a bug in Mongoose and will fix it.
Milestone
Description
Prerequisites
- I have written a descriptive issue title
- I have searched existing issues to ensure the bug has not already been reported
Mongoose version
8.15.1
Node.js version
v22.15.0
MongoDB server version
8.0.9
Typescript version (if applicable)
No response
Description
If you have model with Map field (see repro script, MetaSchema.items), you can use model.set(path, value) only if path does not refer inside the Schema nested in the Map, i.e.:
item.set("items.m3", { field: "field3", arr: [4] }); // OK
item.set("items.m2.field", "replaced"); // does not work
item.set("items.m2.arr", [1]); // does not workAlso, if you have nested Map inside Map field (see repro script, MetaSchema.nested), an error is thrown when trying to call set() with a nested Schema with a nested Map, i.e.:
item.set("nested.inserted", { map: new Map([["a1", 1]]) }); // causes error at `save()` stage
// MongoServerError: Updating the path 'nested.$*.map' would create a conflict at 'nested.$*.map'
item.set("nested.inserted2.map", new Map([["a1", 1]])); // does not work at allSteps to Reproduce
Repro script:
"use strict";
import mongoose from "mongoose";
console.log("Mongoose version", mongoose.version);
await mongoose.connect("mongodb://127.0.0.1:27017/mongoose_test");
await mongoose.connection.dropDatabase();
const MetaSchema = new mongoose.Schema({
items: {
type: Map,
of: new mongoose.Schema(
{
field: { type: String, required: true },
arr: { type: [Number] },
},
{ _id: false }
),
default: new Map(),
},
nested: {
type: Map,
of: new mongoose.Schema(
{
map: {
type: Map,
of: Number,
required: true,
},
},
{ _id: false }
),
default: new Map(),
},
});
const MetaModel = mongoose.model("MetaModel", MetaSchema);
await MetaModel.create({
items: new Map([
["m1", { field: "field1", arr: [1, 2] }],
["m2", { field: "field2", arr: [] }],
]),
nested: new Map([
[
"key",
{
map: new Map([
["k7", 7],
["k8", 8],
["k9", 9],
]),
},
],
[
"key2",
{
map: new Map([["k7", 7]]),
},
],
]),
});
const item = await MetaModel.findOne();
console.log("item", item);
item.set("items.m1.field", "changed");
item.set("items.m2.field", "replaced");
item.set("items.m2.arr", [1]);
item.set("items.m3", { field: "field3", arr: [4] });
item.set("nested.inserted", { map: new Map([["a1", 1]]) });
item.set("nested.inserted2.map", new Map([["a1", 1]]));
console.log(item.modifiedPaths());
console.log(item);
await item.save();
process.exit(0);output:
Mongoose version 8.15.1
item {
_id: new ObjectId('68400944e3a759c9f5472135'),
items: Map(2) {
'm1' => { field: 'field1', arr: [Array] },
'm2' => { field: 'field2', arr: [] }
},
nested: Map(2) { 'key' => { map: [Map] }, 'key2' => { map: [Map] } },
__v: 0
}
[
'items',
'items.$*',
'items.$*.field',
'items.$*.arr',
'items.m3',
'nested',
'nested.$*',
'nested.$*.map',
'nested.$*.map.a1',
'nested.inserted'
]
{
_id: new ObjectId('68400944e3a759c9f5472135'),
items: Map(3) {
'm1' => { field: 'field1', arr: [Array] },
'm2' => { field: 'field2', arr: [] },
'm3' => { field: 'field3', arr: [Array] }
},
nested: Map(3) {
'key' => { map: [Map] },
'key2' => { map: [Map] },
'inserted' => { map: [Map] }
},
__v: 0
}
/Users/holem/Documents/github/mongoose-map-test/node_modules/mongodb/lib/operations/update.js:75
throw new error_1.MongoServerError(res.writeErrors[0]);
^
MongoServerError: Updating the path 'nested.$*.map' would create a conflict at 'nested.$*.map'
at UpdateOneOperation.execute (/Users/holem/Documents/github/mongoose-map-test/node_modules/mongodb/lib/operations/update.js:75:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async tryOperation (/Users/holem/Documents/github/mongoose-map-test/node_modules/mongodb/lib/operations/execute_operation.js:207:20)
at async executeOperation (/Users/holem/Documents/github/mongoose-map-test/node_modules/mongodb/lib/operations/execute_operation.js:75:16)
at async Collection.updateOne (/Users/holem/Documents/github/mongoose-map-test/node_modules/mongodb/lib/collection.js:207:16) {
errorLabelSet: Set(0) {},
errorResponse: {
index: 0,
code: 40,
errmsg: "Updating the path 'nested.$*.map' would create a conflict at 'nested.$*.map'"
},
index: 0,
code: 40
}
Node.js v22.15.0
Expected Behavior
It would be great if model.set() would work with nested Schemas and with nested fields in these Schemas of any supported types (including Maps).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.We've confirmed this is a bug in Mongoose and will fix it.