是否有一种方法可以将created_at和updated_at字段添加到猫鼬模式中,而不必在每次调用new MyModel()时传递它们?

created_at字段将是一个日期,仅在创建文档时添加。 每当对文档调用save()时,updated_at字段将被更新为新的日期。

我已经在我的模式中尝试了这一点,但除非我显式地添加它,否则字段不会显示:

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

当前回答

从mongo 3.6开始,你可以使用'change stream': 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实例应该作为'replica set'运行。 它也可以作为一个1节点的副本集(几乎没有变化,然后独立使用):

运行mongo作为一个副本集: https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/

复制集配置vs独立: Mongo DB -独立和单节点副本集的区别

其他回答

您可以使用猫鼬部队的时间戳插件将此行为添加到任何模式。

如果使用update()或findOneAndUpdate()

带有{upsert: true}选项

你可以使用$setOnInsert

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

在你的模型中:

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

在那之后,你收集的模型是这样的:

{
    "_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"),
}

我的猫鼬版本是4.10.2

似乎只有钩子findOneAndUpdate是工作

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

在您的模型模式中,只需添加一个属性时间戳,并为其赋值为true,如下所示

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