New MyModel()が呼び出されるたびにそれらを渡すことなく、created_atおよびupdated_atフィールドをmongooseスキーマに追加する方法はありますか?
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 }
});
update()
またはfindOneAndUpdate()
を使用する場合
{upsert: true}
オプション付き
$setOnInsert
を使用できます
var update = {
updatedAt: new Date(),
$setOnInsert: {
createdAt: new Date()
}
};
PDATE:(5年後)
注:使用することに決めた場合 Kappa Architecture (Event Sourcing + CQRS)、更新日は不要ですすべて。データは不変の追加専用のイベントログであるため、イベントの作成日のみが必要です。以下で説明するLambda Architectureと同様です。アプリケーションの状態は、イベントログ(派生データ)の投影です。既存のエンティティに関する後続のイベントを受信した場合、そのイベントの作成日をエンティティの更新日として使用します。これは、ミセロサービスシステムで一般的に使用されている(および誤解されている)プラクティスです。
PDATE:(4年後)
ObjectId
name__を_id
フィールドとして使用する場合(通常はそうです)、必要なことは次のとおりです。
let document = {
updatedAt: new Date(),
}
_id
フィールドから作成されたタイムスタンプを取得する方法については、以下の元の回答を確認してください。外部システムのIDを使用する必要がある場合は、Roman Rhrn Nesterovの答えを確認してください。
PDATE:(2.5年後)
Mongooseバージョン4.0以上で #timestamps オプションを使用できるようになりました。
let ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
タイムスタンプを設定すると、mongooseはcreatedAt
name__およびupdatedAt
name__フィールドをスキーマに割り当て、割り当てられるタイプはDate
name__です。
タイムスタンプファイルの名前を指定することもできます。
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
注:重要なデータを含む大きなアプリケーションで作業している場合は、ドキュメントの更新を再検討する必要があります。不変の追加専用データ( lambda architecture )を使用することをお勧めします。これが意味することは、挿入のみを許可するということです。 更新と削除は許可されません!レコードを「削除」したい場合は、いくつかの
timestamp
name __/version
name__フィールドを持つドキュメントの新しいバージョンを簡単に挿入し、deleted
name__フィールドをtrue
name__に設定できます。同様に、ドキュメントを更新する場合は、適切なフィールドが更新され、残りのフィールドがコピーされた新しいドキュメントを作成します。このドキュメントをクエリするには、最新のタイムスタンプまたは最新バージョンのドキュメントを取得します「削除」ではありません(deleted
name__フィールドは未定義またはfalse`です)。データの不変性により、データがデバッグ可能になります。すべてのドキュメントの履歴を追跡できます。問題が発生した場合は、ドキュメントの前のバージョンにロールバックすることもできます。このようなアーキテクチャを使用する場合、
ObjectId.getTimestamp()
だけで十分であり、Mongooseに依存しません。
元の回答:
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();
});
これは私がやったことです:
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();
});
スキーマに組み込みのtimestamps
オプションを使用します。
var ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
これにより、createdAt
およびupdatedAt
フィールドがスキーマに自動的に追加されます。
Mongoose 4.0以降、スキーマでタイムスタンプオプションを設定して、Mongooseでこれを処理できるようになりました。
var thingSchema = new Schema({..}, { timestamps: true });
次のように使用されるフィールドの名前を変更できます。
var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });
これは、作成および更新して達成した方法です。
スキーマ内に、次のように作成および更新を追加しました。
/** *記事スキーマ */ var ArticleSchema = new Schema({ 作成:{ タイプ:日付、 デフォルト:Date.now }、 更新:{ タイプ:日付、 デフォルト:Date.now }、 title:{ type:String、 default: ''、 trim:true、 required: 'タイトルは空白にできません' }、 content:{ type:String、 default: ''、 trim:true }、 user:{ type:Schema.ObjectId、 ref: 'User' } });
次に、記事コントローラー内の記事更新メソッドで追加しました:
/** *記事の更新 */ 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){ return res.status(400).send({ メッセージ:errorHandler.getErrorMessage(err) }); } else { res.json(article); } }); };
太字のセクションは重要な部分です。
mongoose-troop
の timestamp
プラグインを使用して、この動作を任意のスキーマに追加できます。
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true }
});
ItemSchema.set('timestamps', true); // this will add createdAt and updatedAt timestamps
このプラグイン を非常に簡単に使用できます。ドキュメントから:
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'
});
schema pluginを使用してこれを達成することもできます。
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);
私のマングースのバージョンは4.10.2です
フックfindOneAndUpdate
のみが動作しているようです
ModelSchema.pre('findOneAndUpdate', function(next) {
// console.log('pre findOneAndUpdate ....')
this.update({},{ $set: { updatedAt: new Date() } });
next()
})
関数を使用して、計算されたデフォルト値を返します。
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();
});
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を備えています。
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 }
});
これを使用できるので、すべてのテーブルにこのオプションを含める必要はありません。
私は実際にこれを裏で行います
すべてが更新にうまくいく場合:
// 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
});
});