Skip to content

Changed paths are incorrect in schemas with nested Maps #15678

@kballen1

Description

@kballen1

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.19.0

Node.js version

24.9.0

MongoDB server version

6.20.0

Typescript version (if applicable)

No response

Description

When working with a mongoose document containing a map whose values are subdocuments, and those subdocuments contain maps or arrays, change tracking seems to emit completely incorrect paths for the edits of those fields. The resulting update document to mongo is broken and makes updating those nested paths impossible.

Only an issue for existing documents, creating new documents with such nested fields works as expected.

Steps to Reproduce

const { Schema, model } = require("mongoose");

const itemSchema = new Schema({
  name: String,
  itemNum: Number,
  itemTags: [String],
}, { _id: false });

const groupSchema = new Schema({
  items: { type: Map, of: itemSchema, default: {} },
  groupNum: Number,
  groupTags: [String],
}, { _id: false });

const parentSchema = new Schema({
  groups: { type: Map, of: groupSchema, default: {} },
});

const M = model("parentSchema", parentSchema);

// as if read from M.findOne() etc
const x = new M().init({
  groups: {
    g1: {
      items: {
        i1: {
          name: "my item"
        }
      },
      groupTags: ["hi"]
    }
  }
});

// after each test below in isolation (others commented)
// console.log(x.getChanges())

x.groups.get("g1").items.set("i2", { name: "second item" });
// { '$unset': { 'groups.g1.groups.g1.i2': 1 } }

x.groups.get("g1").groupNum = 42;
// { '$set': { 'groups.g1.groupNum': 42 } }  -- looks good!

x.groups.get("g1").groupTags.push("yo");
// { '$unset': { 'groups.g1.groups.g1': 1 } }

x.groups.get("g1").items.get("i1").name = "different item";
// { '$unset': { 'groups.g1.groups.g1.i1.name': 1 } }

x.groups.get("g1").items.get("i1").itemNum = 20;
// { '$unset': { 'groups.g1.groups.g1.i1.itemNum': 1 } }

x.groups.get("g1").items.get("i1").itemTags.push("foo");
// { '$unset': { 'groups.g1.groups.g1.i1.itemTags': 1 } }

Expected Behavior

Modifications for nested paths are generated correctly, i.e. set/push update operators

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions