Skip to content

The default value for subdocument fields is not applied when nested projection is used (find/findOne methods) #13720

@andrei-mashko

Description

@andrei-mashko

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

> 6.6.0

Node.js version

v18.16.1

MongoDB server version

5.0

Typescript version (if applicable)

No response

Description

By default mongoose applies default values for subdocument fields which are missing in mongoDB (find/findOne methods):

const mongoose = require('mongoose');

const connection = mongoose.createConnection('mongodb://localhost:27015/test');

const subSchema = new mongoose.Schema({
	propertyA: { type: String, default: 'A' },
	propertyB: { type: String, default: 'B' },
});
const userSchema = new mongoose.Schema({
	name: String,
	sub: { type: subSchema, default: () => ({}) },
});
const User = connection.model('User', userSchema);

await User.insertMany([{ name: 'user' }]);
await User.updateMany({}, { $unset: { 'sub.propertyA': '' } });

const projectionDoc = await User.findOne({}, { name: 1, sub: 1 });
console.log(projectionDoc.sub.propertyA); // 'A'

But when the nested projection is used (e.g. 'sub.propertyA') it doesn't apply it.

const nestedProjectionDoc = await User.findOne({}, { name: 1, 'sub.propertyA': 1, 'sub.propertyB': 1 });
console.log(nestedProjectionDoc.sub.propertyA); // undefined

Steps to Reproduce

const mongoose = require('mongoose');

const connection = mongoose.createConnection('mongodb://localhost:27015/test');

const subSchema = new mongoose.Schema({
	propertyA: { type: String, default: 'A' },
	propertyB: { type: String, default: 'B' },
});
const userSchema = new mongoose.Schema({
	name: String,
	sub: { type: subSchema, default: () => ({}) },
});
const User = connection.model('User', userSchema);

const main = async () => {
	await User.insertMany([{ name: 'user' }]);
	await User.updateMany({}, { $unset: { 'sub.propertyA': '' } });

	const leanDoc = await User.findOne({}, {}, { lean: true });
	console.log(leanDoc.sub.propertyA); // undefined

	const projectionDoc = await User.findOne({}, { name: 1, sub: 1 });
	console.log(projectionDoc.sub.propertyA); // 'A'

	const nestedProjectionDoc = await User.findOne({}, { name: 1, 'sub.propertyA': 1, 'sub.propertyB': 1 });
	console.log(nestedProjectionDoc.sub.propertyA); // 'A' for =< 6.0.0; undefined for > 6.6.0

	await connection.close();
};

main();

Expected Behavior

No response

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

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions