Skip to content

Map in EmbededDocument, the set function error! #10295

@winnochan

Description

@winnochan

Do you want to request a feature or report a bug?

bug

What is the current behavior?

define a two level Map field in a NestedDocument, when call the inner Map's function (set), it will not automatically add the modified path to the path list.

If the current behavior is a bug, please provide the steps to reproduce.

const mongoose = require("mongoose");

const SecondMapSchema = new mongoose.Schema({
  data: { type: Map, of: Number, default: {}, _id: false },
});

const FirstMapSchema = new mongoose.Schema({
  data: { type: Map, of: SecondMapSchema, default: {}, _id: false },
});

const NestedSchema = new mongoose.Schema({
  data: { type: Map, of: SecondMapSchema, default: {}, _id: false },
});

const TestSchema = new mongoose.Schema({
  _id: Number,
  firstMap: { type: Map, of: FirstMapSchema, default: {}, _id: false },
  nested: { type: NestedSchema, default: {}, _id: false },
});

const Test = mongoose.model("Test", TestSchema);

async function test() {
  await mongoose.connect("mongodb://localhost:27017", {
    useCreateIndex: true,
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useFindAndModify: false,
  });
  const doc = await Test.create({ _id: Date.now() });
  console.log(doc);

  // It's Ok!
  doc.firstMap.set("fisrt", {});
  console.log("Should include firstMap.first", doc.modifiedPaths());
  await doc.save();

  // It's Ok!
  doc.firstMap.get("fisrt").data.set("second", {});
  console.log("Should include firstMap.first.data.second", doc.modifiedPaths());
  await doc.save();

  // It's Ok!
  doc.firstMap.get("fisrt").data.get("second").data.set("final", 3);
  console.log(
    "Should include firstMap.first.data.second.data.final",
    doc.modifiedPaths()
  );
  await doc.save();

  // It's Ok!
  doc.nested.data.set("second", {});
  console.log("Should include nested.data.second", doc.modifiedPaths());
  await doc.save();

  // It's ERROR!
  doc.nested.data.get("second").data.set("final", 3);
  console.error(
    "Should include nested.data.second.data.final, but it's not, ERROR here!!! So data lossed!",
    doc.modifiedPaths()
  );
  await doc.save();

  // But this is OK, have to set the nested to {}, I don't know why
  const okDoc = await Test.create({ _id: Date.now(), nested: {} });
  okDoc.nested.data.set("second", {});
  await okDoc.save();
  okDoc.nested.data.get("second").data.set("final", 3);
  console.log(
    "Should include nested.data.second.data.final",
    okDoc.modifiedPaths()
  );
  await okDoc.save();

  await mongoose.disconnect();
}

test().catch((err) => console.error(err));

What is the expected behavior?

The behavior is written in the code's comment.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

Node: v12.16.3
Mongo: 4.4.6
Mongoose: both 5.10.18 and 5.12.11 are tested and failed

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions