몽구스 스키마에 created_at 및 updated_at 필드 추가


166

new MyModel ()이 호출 될 때마다 생성하지 않고 created_at 및 updated_at 필드를 몽구스 스키마에 추가하는 방법이 있습니까?

created_at 필드는 날짜이며 문서를 만들 때만 추가됩니다. updated_at 필드는 문서에서 save ()가 호출 될 때마다 새로운 날짜로 업데이트됩니다.

내 스키마에서 이것을 시도했지만 필드를 신속하게 추가하지 않으면 필드가 표시되지 않습니다.

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

나는 당신이 한 일을 정확하게했고 그것이 효과가있었습니다. 몽구스 사용하기 4.8.4. 새로운 것일 수 있습니까?
martinedwards

1
이것은 얼마 전부터였습니다.
chovy

예, 위의 기능이 작동한다는 점에 주목할 가치가 있다고 생각했습니다.
martinedwards

답변:


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
동의, 이것은 몽구스 4.0에서 가장 좋은 옵션입니다.
Tadd Giles

258

업데이트 : (5 년 후)

참고 : Kappa Architecture ( Event Sourcing + CQRS ) 를 사용하기로 결정한 경우 업데이트 날짜가 전혀 필요하지 않습니다. 데이터는 변경 불가능한 추가 전용 이벤트 로그이므로 이벤트 작성 날짜 만 있으면됩니다. 아래 설명 된 Lambda 아키텍처 와 유사 합니다. 그런 다음 응용 프로그램 상태는 이벤트 로그 (파생 데이터)의 투영입니다. 기존 엔티티에 대한 후속 이벤트를 수신하면 해당 이벤트의 작성 날짜를 엔티티의 업데이트 날짜로 사용합니다. 이것은 mouseroservice 시스템에서 일반적으로 사용되는 (그리고 일반적으로 오해 된) 연습입니다.

업데이트 : (4 년 후)

필드 ObjectId로 사용 _id하는 경우 (보통 경우) 다음과 같이하면됩니다.

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

_id필드 에서 생성 된 타임 스탬프를 얻는 방법에 대해서는 아래의 원래 답변을 확인하십시오 . 외부 시스템의 ID를 사용해야하는 경우 Roman Rhrn Nesterov의 답변을 확인하십시오.

업데이트 : (2.5 년 후)

몽구스 버전이 4.0 이상인 #timestamps 옵션을 사용할 수 있습니다 .

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

타임 스탬프, 몽구스 할당 createdAtupdatedAt필드를 스키마에 설정하면 할당 된 유형은 Date입니다.

타임 스탬프 파일 이름을 지정할 수도 있습니다.

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

참고 : 중요한 데이터가있는 큰 응용 프로그램을 작업하는 경우 문서 업데이트를 다시 고려해야합니다. 불변의 추가 전용 데이터 ( 람다 아키텍처 )로 작업하는 것이 좋습니다. 이것이 의미하는 것은 삽입물 만 허용한다는 것입니다. 업데이트 및 삭제는 허용되지 않아야합니다! 레코드를 "삭제"하려면 일부 timestamp/ version 파일이 포함 된 새 버전의 문서를 쉽게 삽입 한 다음 deleted필드를 로 설정하면 됩니다 true. 마찬가지로 문서를 업데이트하려는 경우 적절한 필드가 업데이트되고 나머지 필드가 복사 된 새 문서를 만든 다음이 문서를 쿼리하려면 최신 타임 스탬프가있는 문서 또는 최신 버전의 문서를 가져옵니다. "삭제되지 않음"(deleted 필드가 정의되지 않았거나 false입니다.).

데이터 불변성으로 데이터를 디버깅 할 수 있습니다. 모든 문서의 기록을 추적 할 수 있습니다. 문제가 발생하면 이전 버전의 문서로 롤백 할 수도 있습니다. 이러한 아키텍처 ObjectId.getTimestamp()를 사용하면 필요한 모든 것이 있으며 몽구스에 의존하지 않습니다.


원래 답변 :

ID 필드로 ObjectId를 사용하는 경우 필드가 필요하지 않습니다 created_at. ObjectId에는라는 메소드가 getTimestamp()있습니다.

ObjectId ( "507c7f79bcf86cd7994f6c0e"). getTimestamp ()

다음과 같은 출력이 반환됩니다.

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

자세한 정보는 여기 에서 Mongo ObjectID에서 생성 된 날짜를 추출하는 방법

파일을 추가 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에서 어떻게합니까?
Zebra Propulsion Lab

6
그것이 사용되는 솔루션이 아니더라도 매우 흥미 롭습니다.
의식하지 못하는

그러나 날짜 작성 날짜를 뷰에 전달하려면 특수 변수를 설정해야합니까, 아니면 id를 전달해야합니까?

3
초기 답변에 감사하지만 람다 아키텍처 사용을 옹호하는 것은 5 배 수준의 메타 문제를 해결하고 CRUD 앱을 작성 하고이 접근법의 복잡성이 실제로 보장되지 않는 한 간단하게 유지하는 것보다 결코 제공하지 않는 좋은 방법처럼 들립니다. MongoDB에 대해 게시하는 것을 시작한다는 것을 기억하십시오. 처음에는 '확실히'확장되어 MongoDB를 의미있게 확장 할 수있는 모든 기록에 대해 새로운 기록을 요구하고 있습니다. ... 카산드라 섹션이 이동
존 Culviner에게

1
이 답변에 제공된 정보 덕분에 실제 삭제 대신 소프트 삭제를 수행하기 위해 실제로 백엔드 디자인을 변경했습니다. 실제로 유용한 더 깊은 지식을 제공합니다.
Kenna

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. 현재 시간을 로컬 var에 저장하고 new Date ()를 호출 할 때마다 할당하지 말고 처음에는 created_at 및 updated_at가 동일한 예외 값을 갖도록합니다. 2. 새로운 날짜 => 새 Date ()
셰이 Erlichmen

13
ObjectId를 사용하면 거기에서 created_at를 얻을 수 있습니다 .... 별도의 필드가 필요하지 않다는 것을 지적하고 싶습니다. 체크 아웃getTimestamp()
Xerri

6
created_at의 다른 옵션은 모델을-> created_at : {type : Date, default : Date.now}로 변경하는 것입니다.
OscarVGG

1
@ajbraus 스키마 플러그인 만들기
wlingke

2
정적 방법이므로 Date.now()가능한 new Date빠른 속도 대신 사용하십시오
karlkurzer

107

timestamps스키마 에 내장 옵션을 사용하십시오.

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

그러면 스키마에 자동으로 createdAtupdatedAt필드가 추가됩니다 .

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


1
몽구스 버전> = 4.0 필요
Jensen

2
문서가 명확하지 않다는 것을 알았습니다. 이렇게하면 필드가 추가되지만 업데이트 할 때마다 업데이트되는지 확인합니까?
Ludwik

일반적으로 createdAt는 객체가 생성 될 때 항상 한 번만 저장됩니다. updatedAt각각의 새로운 저장시 업데이트됩니다 (obj가 변경 될 때)
codyc4321

1
이 "2016-12-07T11 : 46 : 46.066Z"가 있습니다. 타임 스탬프 형식, 시간대 변경 방법을 설명해 주시겠습니까? mongoDB 서버 시간대를 사용합니까?
Mahesh K

@mcompeau, 답변 주셔서 감사합니다! 나는 그것이 긴 샷이라는 것을 알고 있지만, 이런 식으로 생성 된 필드를 색인으로 사용할 수 있다면 우연히 기억하십니까?
manidos

29

사용하는 경우 update()또는findOneAndUpdate()

{upsert: true}옵션

당신이 사용할 수있는 $setOnInsert

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

1
이것은 대부분의 몽고 라이브러리에서 작동합니다. 답변으로
변경됨

1
Mogo의 기본 _id필드를 사용 하는 경우 createdAt필드 가 필요하지 않습니다 . 자세한 내용은 아래 답변을 확인하십시오.
Pavel Nikolov

1
... 내 원래 답변을 확인하십시오 .
Pavel Nikolov

25

추가 timestamps귀하에게 Schema다음과 같이 createdAt하고 updatedAt당신을 위해 자동 생성

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
몽구스가 당신을 위해이 모든 일을했기 때문에 이것이 최선의 해결책이라는 데 동의합니다.
빈스 Bowdren

예, @VinceBowdren에 동의하십시오
Mr.spShuvo

8

이것이 내가 만들고 업데이트 한 방법입니다.

내 스키마 안에 다음과 같이 생성하고 업데이트했습니다.

   / **
     * 기사 스키마
     * /
    var ArticleSchema = 새 스키마 ({
        만들어진: {
            유형 : 날짜,
            기본값 : Date.now
        },
        업데이트 : {
            유형 : 날짜,
            기본값 : Date.now
        },
        제목 : {
            유형 : 문자열,
            기본: '',
            손질 : 참,
            필수 : '제목은 비워 둘 수 없습니다'
        },
        내용 : {
            유형 : 문자열,
            기본: '',
            손질 : 참
        },
        사용자: {
            유형 : Schema.ObjectId,
            심판 : '사용자'
        }
    });

그런 다음 기사 컨트롤러 내의 기사 업데이트 방법에서 다음을 추가했습니다.

/ **
     * 기사 업데이트
     * /
    exports.update = 함수 (요청, 해상도) {
        var article = 요구 사항;

        article = _.extend (문서, 요청 본문);
        article.set ( "updated", Date.now ());

        article.save (function (err) {
            if (err) {
                res.status (400) .send ({
                    메시지 : errorHandler.getErrorMessage (err)
                });
            } else {
                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

모델 스키마에서 속성 타임 스탬프를 추가하고 다음과 같이 값을 true 로 지정하십시오 .

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

이것은 무엇을 할 것인가?
chovy

타임 스탬프 속성은 각 문서에 created_at 및 updated_at 필드를 추가합니다. Created_at 필드는 문서 작성 시간을 나타내고 updated_at 필드는 문서 작성 시간이 있으면 업데이트 시간을 나타냅니다. 두 필드 값 모두 ISO 시간 형식입니다. 이것이 Chovy의 의심을 분명히하기를 바랍니다.
Pavneet Kaur

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. 그렇지 않으면 모든 문서의 타임 스탬프가 동일합니다. 응용 프로그램이 시작된 시간;)
Max Truxa

나는 당신의 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

machinepack-datetime을 사용하여 날짜 시간을 형식화하십시오.

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
});

머신 팩은 Express 또는 일반 Javascript 세계와 달리 명확한 API로 훌륭합니다.


-2

미들웨어가상을 사용할 수 있습니다 . 다음은 해당 updated_at분야 의 예입니다 .

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

이것이 실제로 언제 설정됩니까? 그리고 지속될 것인가? 지금부터 3 일이 지난 지금도 3 일 전에 날짜가 있었습니까?
chovy

주어진 속성을 변경할 때마다 가상이 호출됩니다 (이 경우) name. 그리고 그렇습니다.
zemirco

이것은 Item 객체의 모든 필드에서 작동합니까? 나는이 솔루션이 내가 원하는 것을 확실하지 않다
chovy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.