स्कीमाओं को बनाने के लिए create_at और updated_at फ़ील्ड जोड़ें


166

क्या कोई ऐसा तरीका है जिससे बनाया हुआ_आट और अपडेटेड_एट फील्ड्स को एक मैंगोज स्कीमा में जोड़ा जा सकता है, उन्हें हर बार नए MyModel () में पास किए बिना कहा जाता है?

Create_at फ़ील्ड एक दिनांक होगी और केवल तभी जोड़ा जाएगा जब कोई दस्तावेज़ बनाया जाएगा। जब भी सेव () किसी डॉक्यूमेंट में कॉल किया जाता है, तो अपडेट की गई तारीख को नई तारीख के साथ अपडेट किया जाएगा।

मैंने इसे अपने स्कीमा में आज़माया है, लेकिन जब तक मैं इसे स्पष्ट रूप से नहीं जोड़ता तब तक यह क्षेत्र दिखाई नहीं देता है:

var ItemSchema = new Schema({
    name    : { type: String, required: true, trim: true }
  , created_at    : { type: Date, required: true, default: Date.now }
});

मैंने वही किया जो आपने किया और यह काम किया। Mongoose का उपयोग 4.8.4। कोई नई बात हो सकती है?
11

1
यह काफी पहले से था।
चॉवी

हाँ, लगा कि यह ध्यान देने योग्य है कि उपरोक्त अब काम करता है।
शहीद हुए

जवाबों:


132

Mongoose 4.0 के रूप में अब आप स्कीम पर टाइमस्टैम्प विकल्प सेट कर सकते हैं, जिसमें Mongoose आपके लिए इसे संभाल सकता है:

var thingSchema = new Schema({..}, { timestamps: true });

आप उपयोग किए गए फ़ील्ड का नाम बदल सकते हैं:

var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });

http://mongoosejs.com/docs/guide.html#timestamps


2
सहमत, यह Mongoose 4.0 में सबसे अच्छा विकल्प है।
तादाद जाइल्स

258

अद्यतन: (5 साल बाद)

नोट: यदि आप कप्पा आर्किटेक्चर ( इवेंट सोर्सिंग + सीक्यूआरएस ) का उपयोग करने का निर्णय लेते हैं , तो आपको अद्यतन तिथि की आवश्यकता नहीं है। चूँकि आपका डेटा एक अपरिवर्तनीय, एपेंड-ओनली ईवेंट लॉग है, इसलिए आपको केवल ईवेंट क्रिएट की गई तिथि की आवश्यकता है। लैम्बडा आर्किटेक्चर के समान , नीचे वर्णित है। फिर आपका एप्लिकेशन स्थिति ईवेंट लॉग (व्युत्पन्न डेटा) का एक प्रक्षेपण है। यदि आपको मौजूदा इकाई के बारे में बाद की घटना प्राप्त होती है, तो आप अपनी इकाई के लिए अद्यतन तिथि के रूप में उस घटना की बनाई गई तारीख का उपयोग करेंगे। यह एक सामान्य रूप से प्रयोग किया जाता है (और आमतौर पर गलत समझा जाता है) micososervice सिस्टम में अभ्यास।

अपडेट करें: (4 साल बाद)

यदि आप ObjectIdअपने _idक्षेत्र (जो आमतौर पर मामला है) के रूप में उपयोग करते हैं , तो आपको बस इतना करना है:

let document = {
  updatedAt: new Date(),
}

_idफ़ील्ड से निर्मित टाइमस्टैम्प प्राप्त करने के तरीके के बारे में नीचे मेरे मूल उत्तर की जाँच करें । यदि आपको बाहरी सिस्टम से आईडी का उपयोग करने की आवश्यकता है, तो रोमन रार्न नेस्टरोव के उत्तर की जांच करें।

अपडेट करें: (2.5 वर्ष बाद)

अब आप mongoose version> = 4.0 के साथ #testestamps विकल्प का उपयोग कर सकते हैं ।

let ItemSchema = new Schema({
  name: { type: String, required: true, trim: true }
},
{
  timestamps: true
});

यदि आपके स्कीमा में टाइमस्टैम्प, मानगो असाइन createdAtऔर updatedAtफ़ील्ड सेट हैं , तो असाइन किया गया प्रकार हैDate

आप टाइमस्टैम्प दायर किए गए नामों को भी निर्दिष्ट कर सकते हैं:

timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }

नोट: यदि आप महत्वपूर्ण डेटा के साथ एक बड़े एप्लिकेशन पर काम कर रहे हैं तो आपको अपने दस्तावेज़ों को अपडेट करने पर पुनर्विचार करना चाहिए। मैं आपको अपरिवर्तनीय, परिशिष्ट-केवल डेटा ( लैम्ब्डा आर्किटेक्चर ) के साथ काम करने की सलाह दूंगा । इसका मतलब यह है कि आप केवल आवेषण की अनुमति देते हैं। अपडेट और डिलीट की अनुमति नहीं दी जानी चाहिए! यदि आप एक रिकॉर्ड को "हटाना" चाहते हैं, तो आप आसानी से कुछ timestamp/ version दायर के साथ दस्तावेज़ का एक नया संस्करण डाल सकते हैं और फिर एक deletedफ़ील्ड सेट कर सकते हैं true। इसी तरह यदि आप किसी दस्तावेज़ को अपडेट करना चाहते हैं - आप एक नया अपडेट करें, जिसमें उपयुक्त फ़ील्ड्स को अपडेट किया जाए और बाकी फ़ील्ड्स को कॉपी किया जाए। तब इस दस्तावेज़ को क्वेरी करने के लिए आपको सबसे नया टाइमस्टैम्प या उच्चतम संस्करण के साथ एक मिलेगा। "डिलीट" नहीं (adeleted क्षेत्र अपरिभाषित या गलत है)।

डेटा अपरिवर्तनीयता सुनिश्चित करती है कि आपका डेटा डीबग करने योग्य है - आप हर दस्तावेज़ के इतिहास का पता लगा सकते हैं। यदि आप कुछ गलत करते हैं तो आप दस्तावेज़ के पिछले संस्करण में भी रोलबैक कर सकते हैं। यदि आप इस तरह की वास्तुकला के साथ जाते हैं ObjectId.getTimestamp(), तो आपको इसकी आवश्यकता है, और यह मोंगोज़ पर निर्भर नहीं है।


मूल ANSWER:

यदि आप ऑब्जेक्टआईड को अपने पहचान क्षेत्र के रूप में उपयोग कर रहे हैं, तो आपको फ़ील्ड की आवश्यकता नहीं है created_at। ObjectIds में एक विधि होती है जिसे कहा जाता है getTimestamp()

ObjectId ( "507c7f79bcf86cd7994f6c0e")। GetTimestamp ()

यह निम्न आउटपुट लौटाएगा:

ISODate ( "2012-10-15T21: 26: 17Z")

अधिक जानकारी यहां मैं कैसे मानगो ऑब्जेक्टिफ़ से बनाई गई तारीख को निकालते हैं

जोड़ने के लिए updated_atदायर किया गया तो आप इस का उपयोग करने की जरूरत है:

var ArticleSchema = new Schema({
  updated_at: { type: Date }
  // rest of the fields go here
});

ArticleSchema.pre('save', function(next) {
  this.updated_at = Date.now();
  next();
});

3
आप कैसे करते हैं कि Mongoose / node.js में?
ज़ेबरा प्रोपल्शन लैब

6
यह जानने के लायक है कि क्या यह समाधान है कि इस्तेमाल किया जाता है, बहुत दिलचस्प नहीं है!
बेखबर

लेकिन अगर मैं दृश्य में तारीख को पास करना चाहता हूं, तो मुझे इसके लिए विशेष चर सेट करना होगा, या आईडी सही पास करना होगा?

3
मैं प्रारंभिक उत्तर की सराहना करता हूं लेकिन लैम्ब्डा आर्किटेक्चर का उपयोग करने की वकालत करना भी मेटा समस्याओं के 5x स्तरों को हल करने का एक शानदार तरीका लगता है और संभवतः सीआरयूडी ऐप बनाने और इसे सरल रखने के बजाय कभी वितरित नहीं किया जाता है जब तक कि इस दृष्टिकोण की जटिलता वास्तव में वारंटेड नहीं है। याद रखें कि आप MongoDB के बारे में पोस्ट कर रहे हैं जो 'मुश्किल से' के साथ शुरू होता है और आप हर लिखने के लिए एक नया रिकॉर्ड बनाने की वकालत कर रहे हैं जो जल्दी से किसी भी सार्थक पैमाने पर मोंगो को मार देगा। इसे कैसंड्रा खंड में ले जाएं ...
जॉन कुल्विनर

1
मैंने वास्तव में वास्तविक डिलीट के स्थान पर सॉफ्ट डिलीट करने के लिए अपने बैकएंड डिज़ाइन को बदल दिया, इस उत्तर में दी गई जानकारी के लिए धन्यवाद। यह कुछ गहरा ज्ञान प्रदान करता है जो वास्तव में उपयोगी है।
केन्ना

133

यह वही है जो मैंने किया:

var ItemSchema = new Schema({
    name    : { type: String, required: true, trim: true }
  , created_at    : { type: Date }
  , updated_at    : { type: Date }
});


ItemSchema.pre('save', function(next){
  now = new Date();
  this.updated_at = now;
  if ( !this.created_at ) {
    this.created_at = now;
  }
  next();
});

8
1. वर्तमान समय को एक स्थानीय संस्करण में संग्रहीत करें और हर बार नई तिथि () को कॉल करने के बजाय इसे असाइन करें, यह सुनिश्चित करेगा कि पहली बार में pass_at और update_at का समान मान हो। 2. नई तारीख => नई तारीख ()
शाय एर्लिचमेन

13
केवल यह बताना चाहेंगे कि यदि आप ObjectId का उपयोग करते हैं तो आप वहां से create_at प्राप्त कर सकते हैं .... आपको अलग फ़ील्ड की आवश्यकता नहीं है। बाहर की जाँच करेंgetTimestamp()
ज़ेर्री

6
Create_at के लिए अन्य विकल्प मॉडल को बदलकर -> create_at: {type: Date, default: Date.now},
OscarVGG

1
@ajbraus एक स्कीमा प्लग इन करें
waleke

2
इसके तेज के Date.now()बजाय जहां संभव हो इसका उपयोग करें new Dateक्योंकि यह एक स्थिर विधि है
karlkurzer

107

timestampsअपने स्कीमा के लिए बिल्ट-इन विकल्प का उपयोग करें ।

var ItemSchema = new Schema({
    name: { type: String, required: true, trim: true }
},
{
    timestamps: true
});

यह आपके स्कीमा में स्वचालित रूप से जोड़ देगा createdAtऔर updatedAtफ़ील्ड बना देगा ।

http://mongoosejs.com/docs/guide.html#timestamps


1
आवश्यक संस्करण> = 4.0
जेन्सेन

2
मैं डॉक्स को अस्पष्ट पाता हूं - यह फ़ील्ड जोड़ता है, लेकिन क्या यह भी सुनिश्चित करता है कि वे हर अपडेट पर अपडेट किए जाते हैं?
लुडविक

आम तौर पर, createAt हमेशा केवल एक बार संग्रहीत किया जाता है ... जब ऑब्जेक्ट बनाया जाता है। updatedAtप्रत्येक नए सेव पर अपडेट किया जाता है (जब
ओब्ज

1
मुझे यह "2016-12-07T11: 46: 46.066Z" मिला .. कृपया समय स्टाम्प प्रारूप की व्याख्या कर सकता है, समय क्षेत्र कैसे बदल सकता है ?? है mongoDB सर्वर समय क्षेत्र ले ??
महेश के

@ mcompeau, उत्तर के लिए धन्यवाद! मुझे पता है कि यह एक लंबा शॉट है, लेकिन क्या आपको किसी भी तरह से याद है अगर इस तरह से बनाए गए क्षेत्रों को सूचकांक के रूप में इस्तेमाल किया जा सकता है?
मनिदोस

29

यदि उपयोग करें update()याfindOneAndUpdate()

{upsert: true}विकल्प के साथ

आप उपयोग कर सकते हैं $setOnInsert

var update = {
  updatedAt: new Date(),
  $setOnInsert: {
    createdAt: new Date()
  }
};

1
यह ज्यादातर मोंगो पुस्तकालयों में काम करता है। स्वीकार्य उत्तर में बदल रहा है
chovy

1
यदि आप मोगो के डिफ़ॉल्ट _idफ़ील्ड का उपयोग कर रहे हैं , तो आपको createdAtफ़ील्ड की आवश्यकता नहीं है । अधिक विवरण के लिए नीचे मेरे उत्तर की जाँच करें।
पावेल निकोलोव

1
... मेरे मूल जवाब की जाँच करें ।
पावेल निकोलोव

25

इस तरह timestampsअपने को जोड़ें और Schemaफिर आपके लिए स्वचालित उत्पन्न होगाcreatedAtupdatedAt

var UserSchema = new Schema({
    email: String,
    views: { type: Number, default: 0 },
    status: Boolean
}, { timestamps: {} });

यहां छवि विवरण दर्ज करें
इसके अलावा, आप बदल सकते हैं createdAt -> created_atद्वारा

timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }

2
अब जब Mongoose आपके लिए यह सब काम करता है, तो मैं मानता हूं कि यह अब सबसे अच्छा समाधान है।
विंस बॉड्रेन

हाँ, उस पर सहमत @VinceBowdren
Mr.spShuvo

8

यह है कि मैंने कैसे बनाया और अद्यतन किया है।

मेरे स्कीमा के अंदर मैंने बनाया और अपडेट किया जैसे:

   / **
     * अनुच्छेद स्कीमा
     * /
    var ArticleSchema = नई स्कीमा ({
        बनाया था: {
            प्रकार: दिनांक,
            डिफ़ॉल्ट: दिनांक
        },
        अद्यतन: {
            प्रकार: दिनांक,
            डिफ़ॉल्ट: दिनांक
        },
        शीर्षक: {
            प्रकार: स्ट्रिंग,
            चूक: '',
            ट्रिम: सच,
            आवश्यक: 'शीर्षक रिक्त नहीं हो सकता'
        },
        सामग्री: {
            प्रकार: स्ट्रिंग,
            चूक: '',
            ट्रिम: सच
        },
        उपयोगकर्ता: {
            प्रकार: स्कीमा।
            रेफरी: 'उपयोगकर्ता'
        }
    });

फिर मैंने जो लेख नियंत्रक जोड़ा उसके अंदर मेरे लेख अद्यतन विधि में:

/ **
     * एक लेख अद्यतन करें
     * /
    Export.update = function (req, res) {
        var लेख = req.article;

        लेख = _.extend (लेख, req.body);
        article.set ("अपडेट किया गया", Date.now ());

        article.save (फ़ंक्शन (इरेट) {
            अगर (गलती से) {
                वापसी res.status (400)। एसेंड ({
                    संदेश: errorHandler.getErrorMessage (इरेट)
                });
            } अन्य {
                res.json (लेख);
            }
        });
    };

बोल्ड सेक्शन ब्याज के हिस्से हैं।



4

आप इस व्यवहार को किसी भी स्कीमा में जोड़ने timestampके mongoose-troopलिए प्लगइन का उपयोग कर सकते हैं ।


3

आप इस प्लगइन का उपयोग बहुत आसानी से कर सकते हैं। डॉक्स से:

var timestamps = require('mongoose-timestamp');
var UserSchema = new Schema({
    username: String
});
UserSchema.plugin(timestamps);
mongoose.model('User', UserSchema);
var User = mongoose.model('User', UserSchema)

और यदि आप चाहें तो खेतों का नाम भी निर्धारित करें:

mongoose.plugin(timestamps,  {
  createdAt: 'created_at', 
  updatedAt: 'updated_at'
});

2

हम स्कीमा प्लगइन का उपयोग करके भी इसे प्राप्त कर सकते हैं।

में helpers/schemaPlugin.jsफ़ाइल

module.exports = function(schema) {

  var updateDate = function(next){
    var self = this;
    self.updated_at = new Date();
    if ( !self.created_at ) {
      self.created_at = now;
    }
    next()
  };
  // update date for bellow 4 methods
  schema.pre('save', updateDate)
    .pre('update', updateDate)
    .pre('findOneAndUpdate', updateDate)
    .pre('findByIdAndUpdate', updateDate);
};

और models/ItemSchema.jsफ़ाइल में:

var mongoose = require('mongoose'),
  Schema   = mongoose.Schema,
  SchemaPlugin = require('../helpers/schemaPlugin');

var ItemSchema = new Schema({
  name    : { type: String, required: true, trim: true },
  created_at    : { type: Date },
  updated_at    : { type: Date }
});
ItemSchema.plugin(SchemaPlugin);
module.exports = mongoose.model('Item', ItemSchema);

2

अपने मॉडल स्कीमा में, बस एक विशेषता टाइमस्टैम्प जोड़ें और इसे दिखाए गए अनुसार सही मान दें : -

var ItemSchema = new Schema({
   name :  { type: String, required: true, trim: true },
},{timestamps : true}
);

यह क्या करेगा?
१०

टाइमस्टैम्प विशेषता प्रत्येक दस्तावेज़ में create_at और updated_at फ़ील्ड जोड़ेगी। Created_at फ़ील्ड दस्तावेज़ के निर्माण के समय को इंगित करता है और update_at फ़ील्ड को अपडेशन के समय को इंगित करता है यदि कोई और दस्तावेज़ का निर्माण समय। दोनों क्षेत्रों का मान आईएसओ समय प्रारूप में है। आशा है कि यह आपके संदेह Chovy को स्पष्ट करेगा।
पावनीत कौर

1
const mongoose = require('mongoose');
const config = require('config');
const util = require('util');

const Schema = mongoose.Schema;
const BaseSchema = function(obj, options) {
  if (typeof(options) == 'undefined') {
    options = {};
  }
  if (typeof(options['timestamps']) == 'undefined') {
    options['timestamps'] = true;
  }

  Schema.apply(this, [obj, options]);
};
util.inherits(BaseSchema, Schema);

var testSchema = new BaseSchema({
  jsonObject: { type: Object }
  , stringVar : { type: String }
});

अब आप इसका उपयोग कर सकते हैं, ताकि हर तालिका में इस विकल्प को शामिल करने की आवश्यकता न हो


1

मेरा मानस संस्करण 4.10.2 है

लगता है केवल हुक findOneAndUpdateकाम है

ModelSchema.pre('findOneAndUpdate', function(next) {
  // console.log('pre findOneAndUpdate ....')
  this.update({},{ $set: { updatedAt: new Date() } });
  next()
})

0

गणना की गई डिफ़ॉल्ट मान वापस करने के लिए एक फ़ंक्शन का उपयोग करें:

var ItemSchema = new Schema({
    name: {
      type: String,
      required: true,
      trim: true
    },
    created_at: {
      type: Date,
      default: function(){
        return Date.now();
      }
    },
    updated_at: {
      type: Date,
      default: function(){
        return Date.now();
      }
    }
});

ItemSchema.pre('save', function(done) {
  this.updated_at = Date.now();
  done();
});

Date.now()फंक्शन में रैप करने की कोई जरूरत नहीं है:...default: Date.now()
karlkurzer

1
मैं इसे एक फ़ंक्शन में लपेटता हूं ताकि मैं परीक्षण में '.now ()' का मजाक उड़ा सकूं। अन्यथा यह इनिशियलाइज़ेशन के दौरान केवल एक बार चलता है और मूल्य आसानी से नहीं बदला जा सकता है।
orourkedd

1
ध्यान दें कि default: Date.now()गलत होगा। अगर यह कुछ भी है default: Date.now। अन्यथा आपके सभी दस्तावेज़ों में समान टाइमस्टैम्प होगा: वह समय जब आपका आवेदन शुरू हुआ था?)
मैक्स ट्रूक्सा

मुझे आपकी default: Date.nowरणनीति पसंद है । बहुत क्लीनर।
orourkedd

0

मैं वास्तव में पीठ में ऐसा करता हूं

यदि सब कुछ अद्यतन के साथ ठीक हो जाता है:

 // All ifs passed successfully. Moving on the Model.save
    Model.lastUpdated = Date.now(); // <------ Now!
    Model.save(function (err, result) {
      if (err) {
        return res.status(500).json({
          title: 'An error occured',
          error: err
        });
      }
      res.status(200).json({
        message: 'Model Updated',
        obj: result
      });
    });

0

डेटाइम को फॉर्मेट करने के लिए मशीनपैक-डेटाइम का उपयोग करें।

tutorialSchema.virtual('createdOn').get(function () {
    const DateTime = require('machinepack-datetime');
    let timeAgoString = "";
    try {
        timeAgoString = DateTime.timeFrom({
            toWhen: DateTime.parse({
                datetime: this.createdAt
            }).execSync(),
            fromWhen: new Date().getTime()
        }).execSync();
    } catch(err) {
        console.log('error getting createdon', err);
    }
    return timeAgoString; // a second ago
});

मशीन पैक एक्सप्रेस या सामान्य जावास्क्रिप्ट दुनिया के विपरीत स्पष्ट एपीआई के साथ बहुत अच्छा है।


-2

आप मिडलवेयर और वर्चुअल का उपयोग कर सकते हैं । यहाँ आपके updated_atक्षेत्र के लिए एक उदाहरण है :

ItemSchema.virtual('name').set(function (name) {
  this.updated_at = Date.now;
  return name;
});

यह वास्तव में कब सेट होगा? और क्या यह जारी रहेगा? तो अब से 3 दिन पहले, यह अभी भी 3 दिन पहले की तारीख होगी?
चॉवी

जब भी आप इस मामले में दी गई संपत्ति को बदलेंगे, तब वर्चुअल को बुलाया जाएगा name। और हाँ, यह लगातार होना चाहिए।
ज़मीरको

क्या यह आइटम ऑब्जेक्ट पर सभी क्षेत्रों के लिए काम करेगा? मुझे यकीन नहीं है कि यह समाधान मुझे क्या चाहिए
9
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.