如何在Mongoose中扩展模式?

时间:2017-12-22 12:39:55

标签: node.js mongodb typescript mongoose

我正在尝试在Mongoose中建立一个复杂的Schema模型,其中一些模式可以用作更复杂的模式的基础,这些模式将共享相同的基本属性,以便不为每个后续模式重复这些模式这需要他们(DRY原则)。最终目标是将所有这些存储在同一个MongoDB集合中。

以下是使用lodash extend对我尝试做的事情的粗略概念:

/* Schemas */

import { Schema } from "mongoose";
import * as _ from 'lodash';

var PersonSchema: Schema = new Schema({
    email:      {type: String, required:true, unique:true},
    lastName:   {type: String, required:true},
    firstName:  {type: String, required:true}
});

export var UserSchema: Schema = _.merge( {}, PersonSchema, {
    password:   {type: String, required:true},
    versionTC:  {type: String, required:true}
});


/* Models */

import mongoose = require("mongoose");
import { Document, Model } from "mongoose";

export interface UserModel extends Document {}
export interface UserModelStatic extends Model<UserModel> {}
export const User = mongoose.model<UserModel, UserModelStatic>("User", UserSchema, "users");

然后,我使用以下配置为POST设置带有Node和Express的用户API:

import { Response, Request, NextFunction, Router } from "express";
import { User, UserModel } from "../models/user";

// Create method
public create(req: Request, res: Response, next: NextFunction) {
    const user = new User(req.body);
    user.save().then(user => {
        res.json(user.toObject());
        next();
    }).catch(next);
}

// POST route, calling the create() method above
router.post("/users", (req: Request, res: Response, next: NextFunction) => {
    new UsersApi().create(req, res, next);
});

使用该设置,每当我尝试发布到我的API时,省略任何新的UserSchema属性(versionTCpassword),用户仍然会被保存到Mongo中,尽管它们是都被定义为required: true

但是,如果我省略PersonSchema(firstNamelastNameemail)中的任何属性,则POST会因预期失败而出现500错误。

最后,如果我在没有使用lodash扩展PersonSchema的情况下在我的UserSchema中定义所有5个属性,则POST请求正文中的任何遗漏属性都将导致500服务器错误(再次,如预期的那样)。

我确信这不是Mongoose的问题,而且我很可能做错了什么,但我无法弄清楚那是什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我最终使用mongoose-extend-schema npm包:

import extendSchema = require('mongoose-extend-schema');

export var UserSchema: Schema = extendSchema(PersonSchema, {
    password:   {type: String, required:true},
    versionTC:  {type: String, required:true}
});