116

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?

Walter Roman
  • 4,621
  • 2
  • 32
  • 36
Liatz
  • 4,997
  • 7
  • 28
  • 33

9 Answers9

171

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

janniks
  • 2,942
  • 4
  • 23
  • 36
drinchev
  • 19,201
  • 4
  • 67
  • 93
  • Thank you very much for the answer but what i'm trying to understand is the best way to query for returning all the records that have been updated in the last 5 minutes. Do you mean I should use : date : {$gt: ((Math.round((new Date()).getTime() / 1000))-300)} – Liatz Apr 04 '12 at 10:02
  • 1
    @user1103897 you can construct a Date object directly and use it with $gt like this: var now = new Date(); var fiveminago = new Date(now.getTime() - 5*60*1000); then query with {date : {$gt:fiveminago}} – mpobrien Apr 12 '12 at 19:09
  • 23
    Should probably be `Date.now` instead of `Date.now()`. – Aleksei Zabrodskii Dec 25 '12 at 19:18
  • 1
    +1 elmigranto, Mongoose docs example uses Date.now http://mongoosejs.com/docs/guide.html – Aaron Jan 19 '13 at 04:29
  • 24
    Explanation: `Date.now` because `Date.now` is a function that will be run when you make objects. `Date.now()` is the date that your `models.js` was parsed. Ie, if you use `Date.now()` all your objects will have the same date, and that will be the date `models.js` was parsed. – mikemaccana Jun 24 '14 at 09:49
  • Your link "timestamps for collections" is leading to a blank page. Can you update your answer, pls? – ShadowGames Jul 05 '23 at 15:27
143

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.

bobbyz
  • 4,946
  • 3
  • 31
  • 42
  • 5
    Thank you, the docs were not clear that one could use `timestamps: true` instead of overriding the names using `timestamps: {...}`. – tar Apr 29 '19 at 16:35
  • 2
    @tar I assume it's still working, but the 4.x docs used to specifically mention `timestamps: true`, so there may be some extra considerations needed going forward. (Maybe they're deprecating it? You're right, the docs aren't very clear for this option.) – bobbyz Apr 30 '19 at 18:23
28

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);
turivishal
  • 34,368
  • 7
  • 36
  • 59
cegprakash
  • 2,937
  • 33
  • 60
  • 2
    Thank you!!! This was super helpful. Was searching documentation but couldn't find how to do this. Thanks again for sharing. – Greg Sep 17 '19 at 19:21
11
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

2
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
});
turivishal
  • 34,368
  • 7
  • 36
  • 59
rajiv patel
  • 319
  • 3
  • 4
1

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.

Jha Nitesh
  • 188
  • 1
  • 11
0

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

Fletch
  • 4,829
  • 2
  • 41
  • 55
0

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

-7

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.

vimuth
  • 5,064
  • 33
  • 79
  • 116