Closed
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.12.1
Node.js version
22.13.9
MongoDB server version
"mongodb-memory-server": "^10.1.4"
Typescript version (if applicable)
^5.8.2
Description
I am trying to migrate a schema from a string to a nested schema object. The getter works, but the new value is not applied to the returned document.
When using toObject with getters, the time string is removed but no new value is applied:
[
{
_id: new ObjectId('67c99f04daa6bc446e6bec72'),
__v: 0,
id: '67c99f04daa6bc446e6bec72'
},
{
_id: new ObjectId('67c99f05daa6bc446e6bec74'),
time: { hours: 12, minutes: 35 },
__v: 0,
id: '67c99f05daa6bc446e6bec74'
}
]
When using lean getters with the "mongoose-lean-getters: "^2.2.1"
plugin, the time string is not replaced.
[
{
_id: new ObjectId('67c99e3dec853f96ef38a72d'),
time: '12:34',
__v: 0
},
{
_id: new ObjectId('67c99e3dec853f96ef38a72f'),
time: { hours: 12, minutes: 35 },
__v: 0
}
]
Steps to Reproduce
Reproduction code:
import mongoose, { Schema } from "mongoose";
import mongooseLeanGetters from "mongoose-lean-getters";
import { MongoMemoryServer } from "mongodb-memory-server";
const mongod = await MongoMemoryServer.create();
const uri = mongod.getUri();
await mongoose.connect(uri);
type Time = { hours: number; minutes: number };
const timeStringToObject = (time: string | Time): Time => {
console.log("runs", time);
if (typeof time !== "string") return time;
const [hours, minutes] = time.split(":");
console.log("time is string", time, {
hours,
minutes,
});
return { hours: parseInt(hours), minutes: parseInt(minutes) };
};
const oldUserSchema = new Schema<{ time: string }>(
{
time: {
type: String,
required: true,
},
},
{}
);
const UserModelName = "User";
const OldUser = mongoose.model(UserModelName, oldUserSchema);
await OldUser.create({ time: "12:34" });
mongoose.deleteModel(UserModelName);
const userSchema = new Schema<{ time: Time }>(
{
time: {
type: new Schema(
{
hours: { type: Number, required: true },
minutes: { type: Number, required: true },
},
{ _id: false }
),
required: true,
get: timeStringToObject,
},
},
{}
);
userSchema.plugin(mongooseLeanGetters, {
defaultLeanOptions: { getters: true },
});
const User = mongoose.model(UserModelName, userSchema);
await User.create({ time: { hours: 12, minutes: 35 } });
const usersLean = await User.find().lean({ getters: true });
console.log(
usersLean,
(await User.find()).map((doc) => doc.toObject({ getters: true }))
);
await mongod.stop();
process.exit();
Expected Behavior
I expect the string to be replaced by the new object.