225

newが呼び出されるupdated_atたびにそれらを渡す必要なしに、created_atとfieldsをマングーススキーマに追加する方法はありますか?MyModel()

この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

22 に答える 22

289

更新:(5年後)

注:Kappaアーキテクチャイベントソーシング+ CQRS )を使用する場合は、日付を更新する必要はありません。データは不変の追加専用イベントログであるため、必要なのはイベント作成日のみです。ラムダアーキテクチャと同様に、以下で説明します。その場合、アプリケーションの状態はイベントログ(派生データ)の予測です。既存のエンティティに関する後続のイベントを受信した場合は、そのイベントの作成日をエンティティの更新日として使用します。これは、ミセロサービスシステムで一般的に使用されている(そして一般的に誤解されている)慣行です。

更新:(4年後)

ObjectIdフィールドとして使用する場合_id(通常はこれが当てはまります)、実行する必要があるのは次のとおりです。

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

_idフィールドから作成されたタイムスタンプを取得する方法については、以下の私の元の回答を確認してください。外部システムからのIDを使用する必要がある場合は、RomanRhrnNesterovの回答を確認してください。

更新:(2。5年後)

これで、マングースバージョン>=4.0で#timestampsオプションを使用できます。

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 filedを含む新しいバージョンのドキュメントを簡単に挿入してから、deletedフィールドをに設定できますtrue。同様に、ドキュメントを更新する場合は、適切なフィールドが更新され、残りのフィールドがコピーされた新しいドキュメントを作成します。次に、このドキュメントをクエリするために、最新のタイムスタンプまたは最高バージョンのドキュメントを取得します。 「削除」されていない(deletedフィールドが未定義またはfalse`)。

データの不変性により、データをデバッグ可能にすることができます。すべてのドキュメントの履歴を追跡できます。問題が発生した場合は、以前のバージョンのドキュメントにロールバックすることもできます。そのようなアーキテクチャObjectId.getTimestamp()を使用する場合、必要なのはそれだけであり、マングースに依存しません。


元の回答:

IDフィールドとしてObjectIdを使用している場合、フィールドは必要ありませんcreated_at。ObjectIdには、と呼ばれるメソッドがありgetTimestamp()ます。

ObjectId( "507c7f79bcf86cd7994f6c0e")。getTimestamp()

これにより、次の出力が返されます。

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

詳細はこちらMongoObjectIDから作成日を抽出するにはどうすればよいですか

filedを追加するには、次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();
});
于 2013-02-28T23:01:31.980 に答える
244

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

于 2015-10-20T17:25:27.657 に答える
136

これは私がやったことです:

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();
});
于 2012-10-01T09:20:54.973 に答える
115

timestampsスキーマの組み込みオプションを使用します。

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

これにより、スキーマcreatedAtにフィールドが自動的に追加されます。updatedAt

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

于 2016-03-07T18:04:25.077 に答える
31

このように追加timestampsすると、自動的に生成されますSchemacreatedAtupdatedAt

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

ここに画像の説明を入力してください
また、あなたはによって変更createdAt -> created_atすることができます

timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
于 2016-11-05T15:33:27.530 に答える
29

使用する場合update()またはfindOneAndUpdate()

{upsert: true}オプション付き

あなたが使用することができます$setOnInsert

var update = {
  updatedAt: new Date(),
  $setOnInsert: {
    createdAt: new Date()
  }
};
于 2014-09-04T15:01:28.403 に答える
9

これが私が作成して更新した方法です。

スキーマ内に、次のように作成および更新されたものを追加しました。

   / **
     *記事のスキーマ
     * /
    var ArticleSchema = new Schema({
        作成した: {
            タイプ:日付、
            デフォルト:Date.now
        }、
        更新しました: {
            タイプ:日付、
            デフォルト:Date.now
        }、
        タイトル: {
            タイプ:文字列、
            デフォルト: ''、
            トリム:true、
            必須:「タイトルを空白にすることはできません」
        }、
        コンテンツ: {
            タイプ:文字列、
            デフォルト: ''、
            トリム:true
        }、
        ユーザー:{
            タイプ:Schema.ObjectId、
            ref:'ユーザー'
        }
    });

次に、記事コントローラー内の記事更新メソッドに次のように追加しました。

/ **
     *記事を更新する
     * /
    exports.update = function(req、res){
        var article = req.article;

        article = _.extend(article、req.body);
        article.set( "updated"、Date.now());

        article.save(function(err){
            if(err){
                res.status(400).send({を返します
                    メッセージ:errorHandler.getErrorMessage(err)
                });
            } そうしないと {
                res.json(記事);
            }
        });
    };

太字のセクションは関心のある部分です。

于 2014-12-10T01:41:27.200 に答える
9

マングースのNestJの場合は、これを使用します

@Schema({timestamps: true})
于 2021-06-09T12:04:58.547 に答える
7
var ItemSchema = new Schema({
    name : { type: String, required: true, trim: true }
});

ItemSchema.set('timestamps', true); // this will add createdAt and updatedAt timestamps

ドキュメント:https ://mongoosejs.com/docs/guide.html#timestamps

于 2019-03-04T07:40:00.137 に答える
7

モデルスキーマで、次のように属性を追加して値をtimestamps割り当てます。-true

var ItemSchema = new Schema({
   name :  { type: String, required: true, trim: true },
},{timestamps : true}
);
于 2019-12-11T13:21:17.290 に答える
7

あなたのmodel

const User = Schema(
  {
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
    password: { type: String, required: true }
  },
  {
    timestamps: true
  }
);

そしてその後、あなたのmodelインcollectionはこのようになります:

{
    "_id" : ObjectId("5fca632621100c230ce1fb4b"),
    "firstName" : "first",
    "lastName" : "last",
    "password" : "$2a$15$Btns/B28lYIlSIcgEKl9eOjxOnRjJdTaU6U2vP8jrn3DOAyvT.6xm",
    "createdAt" : ISODate("2020-12-04T16:26:14.585Z"),
    "updatedAt" : ISODate("2020-12-04T16:26:14.585Z"),
}
于 2021-10-05T09:22:17.067 に答える
4

timestampのプラグインを使用してmongoose-troop、この動作を任意のスキーマに追加できます。

于 2012-10-01T13:47:56.323 に答える
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'
});
于 2015-09-05T23:46:54.047 に答える
3

スキーマプラグインを使用してもこれを実現できる場合があります。

ファイル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);
于 2016-08-29T12:20:33.177 に答える
2

私のマングースのバージョンは4.10.2です

フックだけfindOneAndUpdateが機能しているようです

ModelSchema.pre('findOneAndUpdate', function(next) {
  // console.log('pre findOneAndUpdate ....')
  this.update({},{ $set: { updatedAt: new Date() } });
  next()
})
于 2017-06-01T09:56:41.883 に答える
2

nestjsと@Schemaデコレータを使用している場合は、次のように実現できます。

@Schema({
  timestamps: true,
})

タイムスタンプオプションは、createdAtフィールドとupdatedAtフィールドをスキーマに割り当てるようにmongooseに指示します。割り当てられるタイプは日付です。

デフォルトでは、フィールドの名前はcreatedAtおよびupdatedAtです。

timestamps.createdAtとtimestamps.updatedAtを設定して、フィールド名をカスタマイズします。

于 2021-07-29T06:43:50.463 に答える
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 }
});

これでこれを使用できるため、すべてのテーブルにこのオプションを含める必要はありません。

于 2016-09-16T08:33:24.263 に答える
1

mongo 3.6以降、「ストリームの変更」を使用できます: https ://emptysqua.re/blog/driver-features-for-mongodb-3-6/#change-streams

これを使用するには、「watch」クエリによって変更ストリームオブジェクトを作成する必要があり、変更ごとに、好きなことを行うことができます...

Pythonソリューション:

def update_at_by(change):
    update_fields = change["updateDescription"]["updatedFields"].keys()
    print("update_fields: {}".format(update_fields))

    collection = change["ns"]["coll"]
    db = change["ns"]["db"]
    key = change["documentKey"]

    if len(update_fields) == 1 and "update_at" in update_fields:
        pass  # to avoid recursion updates...
    else:
        client[db][collection].update(key, {"$set": {"update_at": datetime.now()}})


client = MongoClient("172.17.0.2")
db = client["Data"]

change_stream = db.watch()

for change in change_stream:
    print(change)
    update_ts_by(change)

change_streamオブジェクトを使用するには、mongodbインスタンスを「レプリカセット」として実行する必要があることに注意してください。これは、1ノードのレプリカセットとしても実行できます(スタンドアロンで使用する場合はほとんど変更されません)。

レプリカセットとしてmongoを実行します: https ://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/

レプリカセットの構成とスタンドアロン: MongoDB-スタンドアロンと1ノードのレプリカセットの違い

于 2020-09-03T09:38:13.520 に答える
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();
});
于 2015-12-29T20:26:02.717 に答える
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
      });
    });
于 2017-10-27T22:41:31.010 に答える
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
});

マシンパックは、エクスプレスや一般的なJavascriptの世界とは異なり、明確なAPIで優れています。

于 2017-12-08T17:16:33.500 に答える
-2

ミドルウェア仮想を使用できます。updated_atこれがあなたの分野の例です:

ItemSchema.virtual('name').set(function (name) {
  this.updated_at = Date.now;
  return name;
});
于 2012-10-01T09:15:52.963 に答える