继承 Mongoose 模式

Posted

技术标签:

【中文标题】继承 Mongoose 模式【英文标题】:Inheriting Mongoose schemas 【发布时间】:2016-05-23 12:37:03 【问题描述】:

我想创建一个基本的“实体架构”,其他模型实体将从它继承。 我做到了,有点,但奇怪的事情发生了。

这些是我的模式:

AbstractEntitySchema 消息架构 用户架构 RoomSchema

文件:https://github.com/mihaelamj/nodechat/blob/master/models/db/mongo/schemas.js

但在 MongoDB 中,它们都保存在同一个文档存储中:“实体模型”而不是单独的,例如消息、用户...... 我得到了应该发生的事情,但没有得到我想要的,独立的商店吗? 如果是这样,我将创建一个基本的 JSON/对象作为实体,并为每个实体附加适当的属性。或者,还有更好的方法? 谢谢。

【问题讨论】:

【参考方案1】:

Discriminators 是一种模式继承机制。它们使您能够在相同的基础 MongoDB 集合之上拥有多个具有重叠模式的模型。而不是不同的文件。看来你误解了猫鼬的discriminators。这里有一篇文章可以帮助你正确理解它。

Guide to mongoose discriminators


这里有一些代码示例可以满足您的要求,将派生架构保存为单独的文档

function AbstractEntitySchema()    
    //call super        
    Schema.apply(this, arguments);     
    //add                                     
    this.add(                              
        entityName: type: String, required: false,
        timestamp: type: Date, default: Date.now,
        index: type: Number, required: false,
        objectID: type: String,
        id: type: String
    );                                     
;
util.inherits(AbstractEntitySchema, Schema);

//Message Schema
var MessageSchema = new AbstractEntitySchema();
MessageSchema.add(
    text: type: String, required: true,
    author: type: String, required: true,
    type: type: String, required: false
);

//Room Schema
var RoomSchema = new AbstractEntitySchema();
RoomSchema.add(
    name: type: String, required: true,
    author: type: String, required: false,
    messages : [MessageSchema],
);

var Message = mongoose.model('Message', MessageSchema);
var Room = mongoose.model('Room', RoomSchema);

// save data to Message and Room

var aMessage = new Message(
     entityName: 'message',
     text: 'Hello',
     author: 'mmj',
     type: 'article'
    );

 var aRoom = new Room(
     entityName: 'room',
     name: 'Room1',
     author: 'mmj',
     type: 'article'
 );

 aRoom.save(function(err, myRoom)  
    if (err)
        console.log(err);
    else                                  
        console.log("room is saved"); 
 );

 aMessage.save(function(err) 
    if (err)
        console.log(err);
    else
        console.log('user is saved');
 );

【讨论】:

是否将对象添加到单独的消息集合中,我们如何为所有对象使用相同的集合【参考方案2】:

如果您想要多个具有不同 MongoDB 集合的重叠模型,那么您可以使用以下方法:

function extendSchema (Schema, definition, options) 
  return new mongoose.Schema(
    Object.assign(, Schema.obj, definition),
    options
  );

例子

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

const UserSchema = new mongoose.Schema(
  firstname: type: String,
  lastname: type: String
);

const ClientSchema = extendSchema(UserSchema, 
  phone: type: String, required: true
);

您只需扩展用于创建架构的原始对象并在其基础上重新创建新架构。这是您继承的某种抽象模式。

检查这个 npm 模块:https://www.npmjs.com/package/mongoose-extend-schema

【讨论】:

太棒了,这正是我想要的。 与鉴别器相比,更适合我的用例。我在数据库中的所有对象都继承自 CommonMetadata export var ImageSchema: Schema = new Schema( isMock: Boolean, isActive: Boolean, created: Date, updated: Date, ); 感谢您的提示!【参考方案3】:

从 ES6 开始,这同样适用:

var ImageSchema: Schema = new Schema(
    ...CommonMetadataSchema.obj,
    src: String,
    description: String,
);

【讨论】:

这不是 ES6,看起来像 Typescript 什么的。 @mikinoidea 这是一个扩展运算符……它不会扩展附加到架构的方法 如果 ...CommonMetadataSchema 只是一个 JSON 对象而不是猫鼬模式对象,则 Spread 操作确实有效。

以上是关于继承 Mongoose 模式的主要内容,如果未能解决你的问题,请参考以下文章

“基本模式”只返回一种类型而不是 2 (mongodb - mongoose)

文档中的空白字段会占用 Mongoose 的空间吗?

javascript Mongoose Schema继承

ObjectId 的 NodeJS/Mongoose 模式数组

使用嵌套模式引导 Mongoose 模型

将 Joi 模式与 Mongoose 模式一起使用?