I am using Node.js mongodb. I have a model like this
const calendarSchema = new Schema ({
title: String,
start: String, //start date
end: String, // end date
endDate: String,
sessionsRan: Number,
_user: {type: Schema.Types.ObjectId, ref: 'User' },
created: {
type: Date,
default: Date.now
},
})
What is the best way to query mongodb for this? I need to find documents where date < today and isActive: true.
I am currently doing this but not sure how implement a date search
const calendar = await Calendar.find({isActive: "active"})
With $lt mongodb operator, you can query against the date field alongside isActive field.
{start:{$lt: new Date().toISOString()}, isActive: true}
Here's a live demo
Note:
Ensure your dates are saved as ISOString
Your schema for dates should be constructed with new Date() object rather than a String.
Related
I am trying to save the localtime as default when creating an item in mongoose
const ItemSchema = new mongoose.Schema({
item_name: { type: String, required: true },
shop_id: { type: mongoose.Schema.Types.ObjectId, ref: "Shop" },
createTime: { type: Date, default: moment().utcOffset(7) },
});
As you can see I am trying to offset the moment utc time but it is not working? What am I doing wrong?
You're just passing the moment instance to your createTime field and that won't work. After you use .utcOffset() to convert the date to your local time zone, you need to extract it as something that can be understood by mongoose as a date. According to the momentjs doccumentation, the fix should be as easy as adding .format() yo your moment object: moment().utcOffset(7).format().
moment() dose not return a new Date()
mongoose schema expects a Date instance
Try:
const ItemSchema = new mongoose.Schema({
item_name: { type: String, required: true },
shop_id: { type: mongoose.Schema.Types.ObjectId, ref: "Shop" },
createTime: { type: Date, default: new Date(moment().utcOffset(7).format()) },
});
Below is my mongoose Schema out of which createdOn is of type date and default to Date.now().
const SurveyResponseModel = mongoose.Schema({
surveyId: { type: String, required: true },
surveyData: [surveyData],
result : [respResult],
patientId: { type: String },
surveyBy: {type: String},
createdOn: { type: Date, default: Date.now() },
});
Here is how I'm adding new entries to the db.
const newSurvey = new surveyResponseModel({ surveyId, surveyData, surveyBy, patientId, result })
let savedSurvey = await newSurvey.save();
Up until here everything works fine. The problem starts when new entries are made into the schema. I get the same timestamp of createdOn for each new entries.
What am I doing wrong? Is it createdOn: { type: Date, default: Date.now() } a issue or something else. Is it a problem with MongoDB or my node express server? Some help and feedback would really be appreciated.
When this code is executed (at server startup), Date.now() is executed and the result is saved in the object literal, hence that single timestamp will be used for the duration of the server's life.
Try passing the function instead of a value it returns at a single point in time. Mongoose will then call it at runtime.
createdOn: { type: Date, default: Date.now }
How Can we change the value of updated_at whenever Data of DB is updated
Consider this to be my Mongoose Schema,
const mongoose = require('mongoose')
const locationDataSchema = new mongoose.Schema({
locationName: String,
location: [{
lat: Number,
lng: Number
}],
news: [ {
author: String, //or number
title: String,
description: String,
url: String,
urlToImage: String
}],
updated_at: {
type: Date,
default: Date.now
}
})
From my Vaguely reading of Mongoose Docs, I did something like this
locationDataSchema.post('save', (next) => {
console.log("here")
this.locationName = this.locationName.toLowerCase();
this.updated_at = Date.now()
})
But this isn't being called whenever I create/update something in my mongoose Schema
Question: Can someone help me in figuring out how can I change
updated_at = Date.now()
Whenever user updates data in DB (similarly changing location Name to Lowercase)
The current version of Mongoose (v4.x) has time stamping as a built-in option to a schema:
var mySchema = new mongoose.Schema( {name: String}, {timestamps: true} );
This option adds createdAt and updatedAt properties that are timestamped with a Date, and which does all the work for you.
For more please look at
https://mongoosejs.com/docs/guide.html#timestamps
I have 'Patients' and 'Visits.' I would like to find the all the patients who have not had a visit in the last month. I am using mongoose.
Here are my schemas:
var VisitSchema = new mongoose.Schema({
patient: {type: mongoose.Schema.Types.ObjectId, ref: 'patients'},
created: {
type: Date,
default: Date.now
}
});
var PatientSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
visits: [{type: mongoose.Schema.Types.ObjectId, ref: 'visits'}]
});
I would like to be able to do something like...
PatientModel.find({"visits.created": {$not: {$gt: monthAgo} }, err, result)
I have thought about maintaining a field in the Patient model to keep track of the latest visit. Would this be a better approach? If so, what would be the best way to maintain such a field, as visits are added, updated, and deleted?
Assuming all patients have had at least one visit you could query the visits collection using an aggregate pipeline (necessary for grouping):
VisitModel.aggregate() // Make an aggregate pipeline
.sort({created: -1}) // Reverse sort by created date (latest to oldest)
.group({_id: '$patient', lastVisit: {$first: '$created'}}) // get latest visit and project new objects
.match({lastVisit: {$gt: monthAgo}}) // only show patients with lastVisit greater than a month ago
.then(successCallback, errorCallback);
This will result in an array of POJOs that represent the IDs for the patient and the date of their last visit.
I'm using Mongoose, MongoDB, and Node.
I would like to define a schema where one of its fields is a date\timestamp.
I would like to use this field in order to return all of the records that have been updated in the last 5 minutes.
Due to the fact that in Mongoose I can't use the Timestamp() method I understand that my only option is to use the following Javascript method:
time : { type: Number, default: (new Date()).getTime() }
It's probably not the most efficient way for querying a humongous DB.
I would really appreciate it if someone could share a more efficient way of implementing this.
Is there any way to implement this with Mongoose and be able to use a MongoDB timestamp?
Edit - 20 March 2016
Mongoose now support timestamps for collections.
Please consider the answer of #bobbyz below. Maybe this is what you are looking for.
Original answer
Mongoose supports a Date type (which is basically a timestamp):
time : { type : Date, default: Date.now }
With the above field definition, any time you save a document with an unset time field, Mongoose will fill in this field with the current time.
Source: http://mongoosejs.com/docs/guide.html
The current version of Mongoose (v4.x) has time stamping as a built-in option to a schema:
var mySchema = new mongoose.Schema( {name: String}, {timestamps: true} );
This option adds createdAt and updatedAt properties that are timestamped with a Date, and which does all the work for you. Any time you update the document, it updates the updatedAt property. Schema Timestamps Docs.
In case you want custom names for your createdAt and updatedAt
const mongoose = require('mongoose');
const { Schema } = mongoose;
const schemaOptions = {
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' },
};
const mySchema = new Schema({ name: String }, schemaOptions);
var ItemSchema = new Schema({
name : { type: String }
});
ItemSchema.set('timestamps', true); // this will add createdAt and updatedAt timestamps
Docs: https://mongoosejs.com/docs/guide.html#timestamps
Mongoose now supports the timestamps in schema.
const item = new Schema(
{
id: {
type: String,
required: true,
},
{ timestamps: true },
);
This will add the createdAt and updatedAt fields on each record create.
Timestamp interface has fields
interface SchemaTimestampsConfig {
createdAt?: boolean | string;
updatedAt?: boolean | string;
currentTime?: () => (Date | number);
}
This would help us to choose which fields we want and overwrite the date format.
new mongoose.Schema({
description: {
type: String,
required: true,
trim: true
},
completed: {
type: Boolean,
default: false
},
owner: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
}
}, {
timestamps: true
});
I would like to use this field in order to return all the records that have been updated in the last 5 minutes.
This means you need to update the date to "now" every time you save the object. Maybe you'll find this useful: Moongoose create-modified plugin
You can use timestamps:true along with toDateString to get created and updated date.
const SampleSchema = new mongoose.Schema({
accountId: {
type: String,
required: true
}
}, {
timestamps: true,
get: time => time.toDateString()
});
Sample doc in Mongo DB
First : npm install mongoose-timestamp
Next: let Timestamps = require('mongoose-timestamp')
Next: let MySchema = new Schema
Next: MySchema.plugin(Timestamps)
Next : const Collection = mongoose.model('Collection',MySchema)
Then you can use the Collection.createdAt or Collection.updatedAt anywhere your want.
Created on: Date Of The Week Month Date Year 00:00:00 GMT
Time is in this format.