Default values using Mongoose & MongoDB - node.js

In my original schema I had a field :
created: Date
I added a default to this field like so :
created: { type: Date, default: Date.now }
Problem now is that some pre-existing records don't have this field, when these records are fetched the current date time is set for this field in the projected data.
Ideally is it possible, where the record doesn't have the field, to exclude it from the projected data automatically, as it was before adding the schema default?
Failing that, how would I set up an override for the insert operation to set the defaults there instead?

Related

When storing data in MongoDB, the range of Date values is strange

I'm using MongoDB and Mongoose to use a specific schema.
To automatically process data within MongoDB when it is stored, it has the following schema structure:
{
...
createdAt : {
type : Date,
default : Date.now
}
}
Using the schema above, run Mongoose's create, updateOne, and look at the createdAt value stored through MongoDB Compass, the daily time range is set as follows.
2023-01-20T15:00:00.000+00:00 ~ 2023-01-21T14:59:59.999+00:00
In the case of MongoDB, I understand that you cannot set up a separate timezone and that you need to process the time in the Application Layer.
In addition, DB and API servers that use DB are using the "Etc/UTC(UTC+0)" time zone.
In order to solve the above problem, the range of the day was specified as follows to specify a specific time, but the data could not be viewed normally when finding.
const beginDate = moment.utc().startOf('day').toDate(); // 2023-01-21T00:00:00.000Z
const endDate = moment.utc().endOf('day').toDate(); // 2023-01-21T23:59:59.999Z
But is the reason why it is saved like the above time range is because it calls API server in Korea (UTC+9)?

Store wrong timezone in default date and time

I am trying to store default date and time using mongoose with the Node.JS but somehow, it is storing different time zone value in database. I'm using "MongoDB Atlas Database" as a DB server and also configured default time zone with reference to this. I have also tried this for change time zone and also tried "moment-timezone.js", But didn't get any luck.
I just want to store default date and time with Indian standard time format.
Following is my code for the schema.
const testSchema = new mongoose.Schema({
from: String,
to: String,
amount: Number,
message: {
type: String,
default: ""
},
creationdate: {
type: Date,
default: Date.now
}
});
Please help me with this issue. Show me the best way to solve this problem.
MongoDB stores Date fields as a UTC timestamp in milliseconds since the Unix epoch, which is a 64bit integer (53bit in JS). This is also what Date.now() is. There is no timezone component to the data by design.
If you need a consistent timezone format for a Date object, add a virtual field that returns the required timezone adjusted string or object from the date.
const testSchema = new mongoose.Schema({
creationdate: {
type: Date,
default: Date.now
}
});
testSchema.virtual('formattedCreationDate').get(function() {
return this.creationdate.toLocaleString(); // or day.js/luxon
});
If you need a timezone other than the user or system supplied value, store the required TZ data in another field and use that timezone field in the virtual formatting.
The virtual will probably be easier if you use day.js or luxon.

Mongoose returns default value for field even when the field removed from the document

I have a school schema like this:
var SchoolSchema= new mongoose.Schema({
name: {type:String, required: true}
status: { type: String, default: "active" }
});
Mongoose default feature works on two levels:
1) Set field value to default while saving, if the field is not present in the input.
2) While fetching, set field value to default value, if the field is not present in the saved document.
What I wish is for it to set it to default value only while saving, and when fetching a document it should return null value for status if the status property is not present in the record. Currently it returns 'active' when I remove status property from the record.
Is there a way I could do this Mongoose?
What you can do is use the pre-save middleware.
It would look something like this:
schema.pre('save', function(next) {
// Change your fields
next()
})
This code will be activated when you save your mongo document.
Mongoose also adds a isNew field to your object so you could extend this code to only change your fields if this is the first time the document is being save to the DB
schema.pre('save', function(next) {
if (this.isNew) {
// Change your fields
}
next()
})

Passing current time to Mongoose query

I've run into problem. I made field in my Mongoose schema with type "Date":
...
timeOfPassingQuestion: Date,
...
Now, I want to pass current time in hours, minutes, seconds and miliseconds and save it into that field. How should I format my Node variable so I can pass it without errors?
Edit: Also, I forgot to say that I wanna later see how much time user spent answering question by subtracting current time and time that I pulled from DB, timeOfPassingQuestion field.
This is the syntax to create a schema that supports a date field:
// Schema
{ //...
someDate: Date,
}
// date object that you can use whenever you decide to set it
var dateObj = new Date();
This will create a JavaScript date object that you can then pass into your Mongoose object for the date field.
Or, if you will always want it on creation, put it directly in your mongoose schema
{ //...
createdDate: { type: Date, default: Date.now },
}
In order to compare the time in the future, I suggest you use moment.js, then you can query the time difference like so:
moment(Model.createdDate).fromNow();
Sources:
Mongoose Schema
Moment.js fromNow

Sequalize TimeStamps

I was facing a problem with TimeStamps, In my model I've specified like
{
timestamps: true,
createdAt: 'createdOn',
updatedAt: 'updatedOn',
tableName: 'Employee'
});
But in database both createdOn and updatedOn were storing date values, I want updatedOn as null because it was creating newly. Am I missing anything,Thanks in Advance.
Unless you disable it, updatedAt and createdAt are provided by Sequelize without having to manually add them. - http://docs.sequelizejs.com/en/v3/docs/models-definition/#configuration
Creating a new row is considered an update and so yes, updatedAt and CreatedAt will both have the same timestamp on first write. If you really want to track whether or not something is new you might look into using a "status" column with an ENUM (for multiple status values) or a BOOLEAN to represent either new or not - http://docs.sequelizejs.com/en/v3/docs/models-definition/#data-types

Resources