文档架构示例:

var CompanySchema = Schema({
    created: { type: Date, default: Date.now },
    modified: { type: Date, default: Date.now },
    address: { type: String, required:true },
    name: { type: String, required:true }
});

我正在使用一个通用的请求处理程序来编辑和创建"公司"文档:

exports.upsert = function(req, res) {
    helper.sanitizeObject(req.body);
    var company = {
        name: req.body.name,
        address: req.body.address
    };
    var id = req.body.id || new mongoose.Types.ObjectId();
    var queryOptions = {
        upsert: true
    };
    Company.findByIdAndUpdate(id, company, queryOptions).exec(function(error, result) {
        if(!error) {
            helper.respondWithData(req, res, {
                data: result.toJSON()
            });
        } else {
            helper.respondWithError(req, res, helper.getORMError(error));
        }
    });
};

但使用这种方法,当插入新文档时,默认值为Date.now的属性不会保存createdmodified个.现在我可以根据id的存在调用Company.create,但我想知道,如果新文档上不存在属性,为什么upsert不使用默认值?

我用的是mongoose 版本~3.8.10,

推荐答案

目前的情况是,在调用任何"更新"方法家族(如findByIdAndUpdate)时,都不会使用Mongoose的验证、中间件或默认值.它们只能通过拨打savecreate来调用.

原因是"更新"调用实际上是传递给本机驱动程序的,而Mongoose只提供基于模式定义的字段类型转换.

Mongoose 4.0 Update

Mongoose现在支持在updatefindOneAndUpdatefindByIdAndUpdate upsert期间创建新文档时设置默认值.将setDefaultsOnInsert选项设置为true以启用此功能.这将使用$setOnInsert运算符创建插入时的默认值.

var queryOptions = {
    upsert: true,
    setDefaultsOnInsert: true
};
Company.findByIdAndUpdate(id, company, queryOptions).exec( ...

Mongodb相关问答推荐

使用查询参数过滤MongoDB Go驱动程序时出现问题

如何使用MongoDB对子文档进行条件投影?

分组前的 MongoDb 聚合总数

错误起草的 MongoDB 聚合管道 $match 阶段

使用名为 Object 键的 uuid 创建 mongodb 文档

如何将 MongoDB 集合中的 _id 字段更改为 User_id?

使用 Flask-pymongo 扩展通过 _id 在 MongoDB 中搜索文档

将MongoDB连接到前端?

如何检索 MongoDb 集合验证器规则?

加载时将 mongo 存储的日期转换回自 Unix 纪元以来的毫秒数?

在 MongoDb 中查询小于 NOW 的日期时间值

pymongo 排序和 find_one 问题

使用 ObjectId.GenerateNewId() 还是离开 MongoDB 创建一个?

如何在 MongoDB 集合中查找与给定条件匹配的文档和单个子文档

使用 nodejs/mongoose 部分更新子文档

MongoDB Compass 过滤器(查询)

Mongoose.pre('save') 不会触发

没有数组的嵌入文档?

如何在 golang 和 mongodb 中通过 id 查找

在 mongodb 集合中查找最旧/最新的帖子