find,findOne或findById之后的Mongoose save()

时间:2013-11-20 19:27:52

标签: node.js mongodb mongoose

我在更新mongoose文档后遇到使用save()的问题。看起来从find,findOne或findById传递的类型是Mongoose Document而不是模型,因此它缺少save()函数。 update()可用,但它会跳过我需要的中间件。

最近我能找到的是: mongoose - 'save' method does not exist但看起来它仍然将Document传递给我而不是Model实例。

这可能是我的版本吗?使用最新的NPM - 3.8.1

models.StudySubject.findById(id, function (err, studySubject) {
        if (err)
            return cb(err);

        if (!studySubject)
            return cb({ status: 404, error: 'Study subject not found'});

        var subjectInfo = extractSubjectFields(params);
        delete subjectInfo.study; // prevent study change

        updateObjOneLevel(studySubject, subjectInfo);

        studySubject.save(function (err, studySubject, count) {
            if (err)
                return cb(err);

            if (count !== 1)
                return cb({ status: 500, error: 'Error saving Study Subject' });

            cb(null, studySubject);
        });
    });

extractSubjectFields()查看可选更新字段的输入params,例如:

if (params.study)
        subjectInfo.study = params.study;

堆栈跟踪:

Uncaught TypeError: Object #<Object> has no method 'save'
 at C:\....\node_modules\mongoose\lib\document.js:1270:13

架构:

var studySubjectSchema = new mongoose.Schema({
    _id: {
        type: String,
        default: function() { return uuid.v4() },
        match: [/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, "Invalid UUID"]
    },
    study: {
        type: String,
        ref: 'Study',
        required: "Study reference is required: `{PATH}` - `{VALUE}`"
    },
    first_name: {
        type: String,
        encrypt: true
    },
    last_name: {
        type: String,
        encrypt: true
    },
    date_of_birth: {
        type: String,
        encrypt: true
    },
    mrns: [MRNSchema],
    metadata: {
        type: {},
        validation: [function (val) {
            return (typeof val == 'object');
        }, "Metadata field must be a key/value object"]
    },
    enrollments: [{
        type: String,
        match: [/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, "Invalid Enrollment UUID"],
        ref: 'Enrollment'
    }]
});

var enrollmentSchema = new mongoose.Schema({
    _id: {
        type: String,
        default: function() { return uuid.v4() },
        lowercase: true,
        match: [/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, "Invalid UUID"]
    },
    study: {
        type: String,
        ref: 'Study',
        required: "Study reference is required: `{PATH}` - `{VALUE}`"
    },
    first_name: {
        type: String,
        required: true
    },
    last_name: {
        type: String,
        required: true
    },
    date_of_birth: {
        type: String,
        required: true
    },
    mrns: [MRNSchema],
    metadata: {
        type: {},
        validation: [function (val) {
            return (typeof val == 'object');
        }, "Metadata field must be a key/value object"],
    },
    consents: [ConsentSchema],
    subject_study_code: {
        type: String,
        index: true
    },
    unenrolled: {
        type: Date
    }
});

谢谢!

1 个答案:

答案 0 :(得分:0)

它实际上与mrns数组有关。

使用subjectInfo.mrns = deepCopy(params.mrns);

解决了这个问题

我想在代码的其他地方指出了由于某种原因影响将对象添加为数组作为子文档数组。因此,创建一个深层复制修复它。

注释updateObjOneLevel()仍然影响它的原因是有一个pre('save挂钩加密MRN字段(它还加密first_name,last_name,date_of_birth)。这可能是我应该提到的,但并不认为预钩可能会影响它。加密插件也可能是导致它的插件,它有时会加密其他地方引用的对象,这就是应该传递深拷贝的原因。

谢谢大家!!