Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timestamps are not being created #10447

Closed
lbertoncello opened this issue Jul 12, 2021 · 29 comments
Closed

Timestamps are not being created #10447

lbertoncello opened this issue Jul 12, 2021 · 29 comments
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@lbertoncello
Copy link

lbertoncello commented Jul 12, 2021

I'm trying to add timestamps to my nested objects, but it's not working. Timestamps are being set only on the root documents (Church). Am I doing something wrong?

Here's my schemas:

const churchSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
	integration: {
		type: Integration,
		required: true,
	},
	service: {
		type: Service,
		required: true,
	},
	events: {
		type: [ Event ],
		required: false,
	},
}, {
	timestamps: true,
});
const eventSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
	code: {
		type: String,
		required: true,
	},
	template: {
		type: Template,
		required: true,
	},
	users: {
		type: [ User ],
		required: false,
	},
	message: {
		type: Message,
		required: true,
	},
}, {
	timestamps: true,
}
const userSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
	email: {
		type: String,
		required: true,
	},
	fullname: {
		type: String,
		required: true,
	},
	dateOfBirth: {
		type: Date,
		required: true,
	},
	contacted: {
		type: Boolean,
		required: true,
		default: false,
	},
}, {
	timestamps: true,
});

Here's the function I'm using to insert nested documents:

churchSchema.methods.addUserToEvent = async function (user, eventCode) {
	return await mongoose.model('Church').findOneAndUpdate({
		_id: this._id,
		events: {
			$elemMatch: {
				code: eventCode,
				users: {
					$not: {
						$elemMatch: {
							email: user.email,
						},
					},
				},
			},
		},
	}, {
		$addToSet: {
			'events.$.users': user,
		},
	}, {
		upsert: true,
		new: true,
		timestamps: true,
	});
};

MongoDB: 4.4.6
Mongoose: 5.13.2
Node.js: v14.17.0

@IslandRhythms
Copy link
Collaborator

IslandRhythms commented Jul 12, 2021

Please include model creation. Also, are those mixed Schemas you are using?

@lbertoncello
Copy link
Author

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mongoosePaginate = require('mongoose-paginate-v2');

const Event = require('../Event');
const Service = require('../Service');
const Integration = require('../Integration');

const eventCodes = {
	aniversary: 'USUARIO_ANIVERSARIANTE',
	welcome: 'USUARIO_NOVO_CADASTRO',
};

const churchSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
	integration: {
		type: Integration,
		required: true,
	},
	service: {
		type: Service,
		required: true,
	},
	events: {
		type: [ Event ],
		required: false,
	},
}, {
	timestamps: true,
});


/*
 * Plugins
 */
churchSchema.plugin(mongoosePaginate);

/*
 * Indexes
 */
churchSchema.index({ churchId: 1 }, { unique: true });

/*
 * Query helpers
 */
churchSchema.query.byChurchId = async function (churchId) {
	return await this.where({ churchId: churchId });
};

churchSchema.query.byEventCode = async function (code) {
	return await this.where({ 'events.code': code });
};

churchSchema.query.byEventchurchId = async function (churchId) {
	return await this.where({ 'events.churchId': churchId });
};

churchSchema.query.byTemplatechurchId = async function (churchId) {
	return await this.where({ 'events.template.churchId': churchId });
};

churchSchema.query.hasEvent = async function (eventCode) {
	return await this.where({ 'events.code': eventCode });
};


/*
 * Instance methods
 */
churchSchema.methods.getEvent = async function (eventCode) {
	return (await mongoose.model('Church').find({
		_id: this._id,
	}).
		select({
			events: {
				$elemMatch: {
					code: eventCode,
				},
			},
			churchId: true,
		}))[0].events[0];
};

churchSchema.methods.getAniversaryEvent = async function () {
	return await this.getEvent(eventCodes.aniversary);
};

churchSchema.methods.getWelcomeEvent = async function () {
	return await this.getEvent(eventCodes.welcome);
};

churchSchema.methods.addUserToEvent = async function (user, eventCode) {
	return await mongoose.model('Church').findOneAndUpdate({
		_id: this._id,
		events: {
			$elemMatch: {
				code: eventCode,
				users: {
					$not: {
						$elemMatch: {
							email: user.email,
						},
					},
				},
			},
		},
	}, {
		$push: {
			'events.$.users': user,
		},
	}, {
		upsert: false,
		new: true,
	});
};

churchSchema.methods.addUsersToAniversaryEvent = async function (users) {
	return await this.addUsersToEvent(eventCodes.aniversary, users);
};

churchSchema.methods.addUsersToWelcomeEvent = async function (users) {
	return await this.addUsersToEvent(eventCodes.welcome, users);
};

/*
 * Static methods
 */
churchSchema.statics.insertIfNotExists = async function (doc) {
	const query = { churchId: doc.churchId };
	const update = {
		$setOnInsert: {
			id: doc.churchId,
			integration: doc.integration,
			service: doc.service,
			events: doc.events,
		},
	};
	const options = { upsert: true };

	return await mongoose.model('Church').
		findOneAndUpdate(query, update, options);
};

churchSchema.statics.getEventCodes = function () {
	return eventCodes;
};


churchSchema.statics.getUsersNotContacted = async function (
	churchId,
	eventCode,
) {
	return await mongoose.model('Church').aggregate([
		{
			$match: {
				churchId: churchId,
			},
		},
		{
			$project: {
				churchId: 1,
				events: 1,
			},
		},
		{
			$unwind: {
				path: '$events',
				preserveNullAndEmptyArrays: false,
			},
		},
		{
			$match: {
				'events.code': eventCode,
			},
		},
		{
			$unwind: {
				path: '$events.users',
				preserveNullAndEmptyArrays: false,
			},
		},
		{
			$match: {
				'events.users.contacted': false,
			},
		},
		{
			$group: {
				_id: '$_id',
				churchId: {
					$first: '$churchId',
				},
				users: {
					$push: '$events.users',
				},
			},
		},
	]);
};

mongoose.model('Church', churchSchema);

@lbertoncello
Copy link
Author

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const Template = require('../Template');
const User = require('../User');
const Message = require('../Message');

const eventSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
	code: {
		type: String,
		required: true,
	},
	template: {
		type: Template,
		required: true,
	},
	users: {
		type: [ User ],
		required: false,
	},
	message: {
		type: Message,
		required: true,
	},
}, {
	timestamps: true,
});

/*
 * Indexes
 */
eventSchema.index({ churchId: 1 }, { unique: true });


/*
 * Query helpers
 */
eventSchema.query.byCode = function (code) {
	return this.where({ code: code });
};

eventSchema.query.onlyAniversary = function () {
	const code = 'USUARIO_ANIVERSARIANTE';

	return this.where({ code: code });
};

eventSchema.query.onlyWelcome = function () {
	const code = 'USUARIO_NOVO_CADASTRO';

	return this.where({ code: code });
};

/*
 * Static methods
 */


mongoose.model('Event', eventSchema);

@lbertoncello
Copy link
Author

lbertoncello commented Jul 12, 2021

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
	email: {
		type: String,
		required: true,
	},
	churchId: {
		type: Number,
		required: true,
	},
	fullname: {
		type: String,
		required: true,
	},
	dateOfBirth: {
		type: Date,
		required: true,
	},
	contacted: {
		type: Boolean,
		required: true,
		default: false,
	},
}, {
	timestamps: true,
});

/*
 * Indexes
 */
userSchema.index({
	email: 1,
	churchId: 1,
}, { unique: true });

/*
 * Query helpers
 */
userSchema.query.byEmail = function (email) {
	return this.where({ email: email });
};


userSchema.query.byDateOfBirth = function (dateOfBirth) {
	return this.where({ dateOfBirth: dateOfBirth });
};

userSchema.query.byDateOfBirthGteThan = function (dateOfBirth) {
	return this.where({
		dateOfBirth: {
			$gte: dateOfBirth,
		},
	});
};

userSchema.query.byDateOfBirthLteThan = function (dateOfBirth) {
	return this.where({
		dateOfBirth: {
			$lte: dateOfBirth,
		},
	});
};

userSchema.query.byDateOfBirthBetween = function (startDate, endDate) {
	return this.where({
		dateOfBirth: {
			$gte: startDate,
			$lte: endDate,
		},
	});
};

mongoose.model('User', userSchema);


@lbertoncello
Copy link
Author

Also, are those mixed Schemas you are using?

Do you need something else?

@IslandRhythms
Copy link
Collaborator

Integration and Service

@lbertoncello
Copy link
Author

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const integrationSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
}, {
	_id: false,
});

/*
 * Indexes
 */


/*
 * Query helpers
 */


/*
 * Instance methods
 */

mongoose.model('Integration', integrationSchema);

@lbertoncello
Copy link
Author

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const serviceSchema = new Schema({
	churchId: {
		type: Number,
		required: true,
	},
	code: {
		type: String,
		required: true,
	},
}, {
	_id: false,
});

/*
 * Indexes
 */


/*
 * Query helpers
 */


/*
 * Instance methods
 */

mongoose.model('Service', serviceSchema);

@lbertoncello
Copy link
Author

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const messageSchema = new Schema({
	numberOfMessages: {
		type: Number,
		required: true,
		default: '0',
	},
}, {
	timestamps: true,
});

mongoose.model('Message', messageSchema);

@lbertoncello
Copy link
Author

Integration and Service

Let me know if you need anything else

@IslandRhythms
Copy link
Collaborator

And you're not getting an error message at all?

@lbertoncello
Copy link
Author

And you're not getting an error message at all?

No, I'm not receiving any error messages. Everything runs fine, but when I check my database, there is no "createdAt" or "updatedAt" in users or events, only in churches.

@lbertoncello
Copy link
Author

Here is an example

/** 
* Paste one or more documents here
*/
/** 
* Paste one or more documents here
*/
{
    "churchId": 5,
    "__v": 0,
    "createdAt": {
        "$date": "2021-07-12T13:55:08.663Z"
    },
    "events": [{
        "users": [{
            "contacted": false,
            "_id": {
                "$oid": "60ec49c1d5a6a8457c6c8ba7"
            },
            "email": "lucast09@gmail.com",
            "churchId": 5,
            "fullname": "Lucas Teste 09",
            "dateOfBirth": {
                "$date": "2020-07-12T00:00:00.000Z"
            }
        }, {
            "contacted": false,
            "_id": {
                "$oid": "60ec49c1d5a6a8457c6c8ba8"
            },
            "email": "lucast10@gmail.com",
            "churchId": 5,
            "fullname": "Lucas Teste 10",
            "dateOfBirth": {
                "$date": "2020-07-12T00:00:00.000Z"
            }
        }],
        "_id": {
            "$oid": "60ec49bcd5a6a8457c6c8b9a"
        },
        "template": {
            "churchId": 1,
            "template": "Feliz aniversário {{usuario.nome}}!"
        },
        "churchId": 1,
        "code": "USUARIO_ANIVERSARIANTE"
    }, {
        "users": [{
            "contacted": false,
            "_id": {
                "$oid": "60ec49bed5a6a8457c6c8b9e"
            },
            "email": "lucast10@gmail.com",
            "churchId": 5,
            "fullname": "Lucas Teste 10"
        }, {
            "contacted": false,
            "_id": {
                "$oid": "60ec49bed5a6a8457c6c8b9f"
            },
            "email": "lucast09@gmail.com",
            "churchId": 5,
            "fullname": "Lucas Teste 09"
        }, {
            "contacted": false,
            "_id": {
                "$oid": "60ec49bed5a6a8457c6c8ba0"
            },
            "email": "lucast08@gmail.com",
            "churchId": 5,
            "fullname": "Lucas Teste 08"
        }, {
            "contacted": false,
            "_id": {
                "$oid": "60ec49bed5a6a8457c6c8ba1"
            },
            "email": "lucast07@gmail.com",
            "churchId": 5,
            "fullname": "Lucas Teste 07"
        }],
        "_id": {
            "$oid": "60ec49bcd5a6a8457c6c8b9b"
        },
        "template": {
            "churchId": 2,
            "template": "Seja bem-vindo {{usuario.nome}}!"
        },
        "churchId": 2,
        "code": "USUARIO_NOVO_CADASTRO"
    }],
    "integration": {
        "churchId": 1
    },
    "service": {
        "churchId": 1,
        "code": "WHATS_APP"
    },
    "updatedAt": {
        "$date": "2021-07-12T13:55:13.176Z"
    }
}

@IslandRhythms IslandRhythms added the confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. label Jul 12, 2021
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');
const {Schema} = mongoose;

const userSchema = new Schema({
	email: {
		type: String,
		required: true,
	},
	fullname: {
		type: String,
		required: true,
	},
	dateOfBirth: {
		type: Date,
		required: true,
	},
	contacted: {
		type: Boolean,
		required: true,
		default: false,
	},
}, {
	timestamps: true,
});

const eventSchema = new Schema({
	code: {
		type: String,
		required: true,
	},
	template: String,
	users: {
		type: [ userSchema ],
		required: false,
	},
	message: String,
}, {
	timestamps: true,
});


const churchSchema = new Schema({
	integration: String,
	service: String,
	events: {
		type: [ eventSchema ],
		required: false,
	},
}, {
	timestamps: true,
});

const Test = mongoose.model('Church', churchSchema);
async function run() {
    await mongoose.connect('mongodb://localhost:27017/test', {
        useNewUrlParser: true,
        useUnifiedTopology: true,
      });
      await mongoose.connection.dropDatabase();
    
     const entry = await Test.create({integration: 'Hello', service: 'world', events: [{code: 'A', template: 'B', users:[{email:'Test@testerson.com', fullname: 'Fullname', dateOfBirth: new Date(), contacted: true}],message:'message'}]})
     const result = await Test.findOneAndUpdate({_id: entry._id, events: {$elemMatch: {code: 'A'}}}, {$addToSet: {'events.$.users':{email: 'randal@test.com', fullName: 'fred', dateOfBirth: new Date(), contacted: true}}},{upsert: true, new: true, timestamps: true});
      console.log(result);
      console.log(result.events[0].users)
}

run();

@lbertoncello
Copy link
Author

const mongoose = require('mongoose');
const {Schema} = mongoose;

const userSchema = new Schema({
	email: {
		type: String,
		required: true,
	},
	fullname: {
		type: String,
		required: true,
	},
	dateOfBirth: {
		type: Date,
		required: true,
	},
	contacted: {
		type: Boolean,
		required: true,
		default: false,
	},
}, {
	timestamps: true,
});

const eventSchema = new Schema({
	code: {
		type: String,
		required: true,
	},
	template: String,
	users: {
		type: [ userSchema ],
		required: false,
	},
	message: String,
}, {
	timestamps: true,
});


const churchSchema = new Schema({
	integration: String,
	service: String,
	events: {
		type: [ eventSchema ],
		required: false,
	},
}, {
	timestamps: true,
});

const Test = mongoose.model('Church', churchSchema);
async function run() {
    await mongoose.connect('mongodb://localhost:27017/test', {
        useNewUrlParser: true,
        useUnifiedTopology: true,
      });
      await mongoose.connection.dropDatabase();
    
     const entry = await Test.create({integration: 'Hello', service: 'world', events: [{code: 'A', template: 'B', users:[{email:'Test@testerson.com', fullname: 'Fullname', dateOfBirth: new Date(), contacted: true}],message:'message'}]})
     const result = await Test.findOneAndUpdate({_id: entry._id, events: {$elemMatch: {code: 'A'}}}, {$addToSet: {'events.$.users':{email: 'randal@test.com', fullName: 'fred', dateOfBirth: new Date(), contacted: true}}},{upsert: true, new: true, timestamps: true});
      console.log(result);
      console.log(result.events[0].users)
}

run();

I've tried to run and it worked but I didn't understand, is it a bug or a mistake of mine?

@IslandRhythms
Copy link
Collaborator

when you ran it you saw timestamps where they should be?

@lbertoncello
Copy link
Author

when you ran it you saw timestamps where they should be?

Yes.

@IslandRhythms
Copy link
Collaborator

paste your output please.

@lbertoncello
Copy link
Author

paste your output please.

node .\test.js
(node:25180) DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify` option set to false are deprecated. See: https://mongoosejs.com/docs/deprecations.html#findandmodify
(Use `node --trace-deprecation ...` to show where the warning was created)
{
  _id: 60ec836110e61f625c7750ff,
  integration: 'Hello',
  service: 'world',
  events: [
    {
      _id: 60ec836110e61f625c775100,
      code: 'A',
      template: 'B',
      users: [Array],
      message: 'message',
      createdAt: 2021-07-12T18:01:05.897Z,
      updatedAt: 2021-07-12T18:01:05.897Z
    }
  ],
  createdAt: 2021-07-12T18:01:05.897Z,
  updatedAt: 2021-07-12T18:01:05.917Z,
  __v: 0
}
[
  {
    contacted: true,
    _id: 60ec836110e61f625c775101,
    email: 'Test@testerson.com',
    fullname: 'Fullname',
    dateOfBirth: 2021-07-12T18:01:05.887Z,
    createdAt: 2021-07-12T18:01:05.897Z,
    updatedAt: 2021-07-12T18:01:05.897Z
  },
  {
    contacted: true,
    _id: 60ec836110e61f625c775103,
    email: 'randal@test.com',
    dateOfBirth: 2021-07-12T18:01:05.915Z
  }
]

@IslandRhythms
Copy link
Collaborator

{
contacted: true,
_id: 60ec836110e61f625c775103,
email: 'randal@test.com',
dateOfBirth: 2021-07-12T18:01:05.915Z
}

this should have timestamps correct?

@lbertoncello
Copy link
Author

{
contacted: true,
_id: 60ec836110e61f625c775103,
email: 'randal@test.com',
dateOfBirth: 2021-07-12T18:01:05.915Z
}

this should have timestamps correct?

Yes, you're right! Sorry, I didn't notice the only the first user has a timestamp.

@lbertoncello
Copy link
Author

@IslandRhythms So the problem is in findOneAndUpdate?

@IslandRhythms
Copy link
Collaborator

We'll have to investigate so can't really say right now. This is a bug

@lbertoncello
Copy link
Author

We'll have to investigate so can't really say right now. This is a bug

Okay, let me know if I can do anything to help.

@sanket-hv
Copy link

I did this await Wallpaper.create(data, {session}) instead of
let wallpaper = new Wallpaper(data, { session })
wallpaper = await wallpaper.save()

and it works for me.

@adityamms
Copy link

I did this await Wallpaper.create(data, {session}) instead of let wallpaper = new Wallpaper(data, { session }) wallpaper = await wallpaper.save() and it works for me.

this is work well for me ,thanks brother

@sanket-hv
Copy link

sanket-hv commented Sep 6, 2023 via email

@rajathongal
Copy link

rajathongal commented Sep 10, 2023

We'll have to investigate so can't really say right now. This is a bug

This issue with timestamps is still there and also strict is not working @IslandRhythms

@vkarpov15
Copy link
Collaborator

@rajathongal please open a new issue and follow the issue template

@Automattic Automattic locked as resolved and limited conversation to collaborators Sep 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
Development

No branches or pull requests

6 participants