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
Related
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.
I want to delete a particular task document automatically. createdAt: {type: Date} => it will take future date and time, and duration:{type: String} => it will take time in hours. whenever the future time arrives from that time to next how much duration we insert, after completion of duration the task document will delete
const mongoose = require('mongoose')
const TaskSchema = new mongoose.Schema({
taskName: { type: String, required: true },
description: { type: String },
creator: { type: String },
duration: { type: String },
createdAt: {type: Date}
})
const Tasks = mongoose.model('Task', TaskSchema)
module.exports = Tasks```
**Please help how to approach this task**
try this
const TestSchema = new Schema({
expire_at: {type: Date, default: Date.now, expires: "your desired value"}
})
this is the solution you are looking for here
I'm Trying to embed a subdocument into my main document,like this:
This is the main document.js
var mongoose = require('../../db/mongodb.connector'),
Schema = mongoose.Schema;
require('./document.model');
var Document= mongoose.model('Document');
require('./alert.model');
var Alert = mongoose.model('Alert');
var userSchema = new Schema({
name: { type: String }
created: { type: Date, default: Date.now()},
alerts: {type: Schema.ObjectId,ref: 'Alert'},
documents: [{type: Schema.ObjectId,ref: 'Document'}],
});
module.exports = mongoose.model('User', userSchema);
This is the embed document.js
var mongoose = require('../../db/mongodb.connector'),
Schema = mongoose.Schema;
var alertsSchema = new Schema({
push: {type: String, default: "true"},
email: {type: String, default: "false"},
sms: {type: String, default: "false"}
});
module.exports = mongoose.model('Alert', alertsSchema);
When I Insert a new User document like this:
exports.insertUser = function (userData, res) {
var user = new User({
name: userData.name,
alerts: {push: "true", email:"false", sms: "false"}
});
user.save...
...
The returned data is this:
{ name: 'name',
documents: [],
created: 2017-04-14T10:22:05.612Z
}
The problem is that I don't know if I'm doing correctly the sintax of embed document because the insert doesn't return any error but the alerts object doesn't appear into the inserted new document.
What would be wrong?
You are doing it wrong. You need to first save the alert document and then use its id in the user document.
let alertDoc = await new Alert({push: "true", email:"false", sms: "false"}).save();
// now use the id in the user doc
await new User({name: userData.name,alerts: alertDoc._id }).save()
In case you want to embed the whole document instead of just storing the ref. You could modify schema of user model. Define your schema like this.
var alertsSchema = new Schema({
push: {type: String, default: "true"},
email: {type: String, default: "false"},
sms: {type: String, default: "false"}
});
....
var userSchema = new Schema({
name: { type: String }
created: { type: Date, default: Date.now()},
alerts: alertsSchema,
documents: [{type: Schema.ObjectId,ref: 'Document'}],
});
....
// now this should work
var user = new User({
name: "<some name>",
alerts: {push: "true", email:"false", sms: "false"}
});
There is a small issue in userSchema. From your schema definition, it looks like you want to store only references to alerts and documents. The right syntax here would be alerts: {type: Schema.Types.ObjectId,ref: 'Alert'}. Please notice that extra Types in it.
Another issue here is, you are trying to store complete alert object inside user document. Mongoose can't allow that, as in your schema, you have told mongoose to save only references to the alert document. So what you need to do here is, create an alert document, get it's _id and then store it in alert field of user document.
Whenever you want to fetch the complete user schema, you can just populate alert and documents.
Hope this answer improves your understanding of how mongoose schema works.
I'm using mongoose.js on a node.js server connecting to mongodb and
I have a mongoose model like the following
SubSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
mongoose.model('SubModel', SubSchema);
MainSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
subs: [SubSchema],
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
var MainModel mongoose.model('MainModel', MainSchema);
which i pull with a command like this
var q = MainModel.find({})
.sort('created', -1)
.limit(25)
.populate("_member")
.populate("subs._member")
.populate("subs.members");
q.execFind(function(err, mains){
//mains[0].subs[0].members - will always be empty why?
});
my problem is that i can't get subs.members array to populate or even load, it just keeps showing as an empty array.
I've tried .populate("subs.members") to no avail even though subs._member loads just fine
try this
SubSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
var SubModel = mongoose.model('SubModel', SubSchema);//add
MainSchema = new Schema({
_member: {type: ObjectId, ref: 'Member'},
subs: [SubSchema],
members: [{type: ObjectId, ref: 'Member'}],
created: { type: Date, default: Date.now }
});
var MainModel = mongoose.model('MainModel', MainSchema);
MainModel.find({})
.sort('created', -1)
.limit(25)
.populate("_member")
.populate("subs._member")
.exec(function(err, mains){
//add
SubModel.populate(mains,{
path:'subs.members'
},function(err,mains){
//mains[0].subs[0].members - is not empty
});
});
#leesei: I can't comment on your post (too little rep), so I leave this as a separate answer.
In mongoose 3.6 subdoc population still doesn't work, the issue github.com/LearnBoost/mongoose/issues/1381 has been closed 7 months ago with the following solution as a workaround. I had to change it slightly to merge the populated subdocument back to the main document.
The subdocument's model Story has to be specified explicitly:
Person.findById(user1._id).populate("stories")
.exec(function(err, doc {
Story.populate(doc.stories, {path: 'creator'}, function (err, stories) {
doc.stories = stories;
return doc;
})
})
In the solution above this works:
Story.populate(doc.stories, {path: 'creator'}, callback)
but this still won't work:
Story.populate(doc, {path: 'stories.creator'}, callback)
Follow-up on #JohnnyHK's post, you can specify the Model to use in populate() for now:
https://github.com/LearnBoost/mongoose/issues/1377#issuecomment-15920370
I had several nest layers deep of sub docs, and none of the supplied options worked for me. I found this amazing Mongoose plugin that will do deep population seamlessly. You just use the same syntax you would expect to work with populate, but it actually works.
https://github.com/buunguyen/mongoose-deep-populate
I have something that looks a slightly different but populates the document with the array items. I'm wondering if it's the objectid's that are causing the issues.
var mongoose = require('mongoose');
var Schema = mongoose.Schema, ObjectID = Schema.ObjectId;
var SubSchema = new Schema({
testsub: String,
created: { type: Date, default: Date.now }
});
var MainSchema = new Schema({
test: String
subs: [SubSchema],
created: { type: Date, default: Date.now }
});
mongoose.model('MainSchema', MainSchema, mainschema);
var query = MainSchema.find({});
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.