Nodejs egg-mongoose 的写法怎么实现 Discriminators?

发布于 1周前 作者 h691938207 来自 nodejs/Nestjs

Nodejs egg-mongoose 的写法怎么实现 Discriminators?

正常的 Mongoose 里 不使用 Discriminators 的写法:

> models/book.js

// Define our Book schema
const BookSchema = new mongoose.Schema(
  {
    title: { type: String, required: true },
    author: { type: String, required: true },
    release_date: { type: Date, required: true },
  }
);

// Create a model from our schema
module.exports = mongoose.model('Book', BookSchema);
> models/movie.js

const MovieSchema = new mongoose.Schema(
  {
    title: { type: String, required: true },
    director: { type: String, required: true },
    release_date: { type: Date, required: true },
  }
);

module.exports = mongoose.model('Movie', MovieSchema);

使用 Discriminators 的写法:

> models/book.js

const baseOptions = { discriminatorKey: ‘itemtype’, // our discriminator key, could be anything collection: ‘items’, // the name of our collection };

const Base = mongoose.model(‘Base’, new mongoose.Schema({ title: { type: String, required: true }, date_added: { type: Date, required: true }, redo: { type: Boolean, required: false }, }, baseOptions, ), );

module.exports = mongoose.model(‘Base’);

> models/book.js

const Base = require('./base'); // we have to make sure our Book schema is aware of the Base schema

const Book = Base.discriminator('Book', new mongoose.Schema({
    author: { type: String, required: true },
  }),
);

module.exports = mongoose.model('Book');
> models/movie.js

const Base = require('./base');

const Movie = Base.discriminator('Movie', new mongoose.Schema({
    director: { type: String, required: true },
  }),
);

module.exports = mongoose.model('Movie');

上面的例子在 egg-mongoose 里这样写:

> {app_root}/app/model/base.js

module.exports = app => { const mongoose = app.mongoose; const Schema = mongoose.Schema;

const baseOptions = { discriminatorKey: ‘itemtype’, // our discriminator key, could be anything collection: ‘items’, // the name of our collection };

const BaseScheme = new Schema({ title: { type: String, required: true }, date_added: { type: Date, required: true }, redo: { type: Boolean, required: false }, }, baseOptions);

return mongoose.model(‘Base’, BaseScheme); };

> {app_root}/app/model/book.js

const Base = require('./base');

module.exports = app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
  
  const BookSchema = new Schema({
    author: { type: String, required: true },
  });
  
  return Base.discriminator('Book', BookSchema);
};

这样做会报错,提示:

ERROR 30161 nodejs.TypeError: Base.discriminator is not a function

请问在 egg-mongoose 中在保持 model 分离的前提下如何实现上述功能?

其他

上面例子的代码源自 Getting started with Mongoose discriminators in Express.js


1 回复

在 Node.js 中使用 egg-mongoose 实现 Mongoose 的 Discriminators(判别器),可以让你在同一个集合中存储多种模型类型。以下是一个简单的实现示例:

首先,确保你已经安装了 mongooseegg-mongoose 插件。

  1. 配置 egg-mongoose: 在 config/plugin.js 中启用 mongoose 插件:

    exports.mongoose = {
      enable: true,
      package: 'egg-mongoose',
    };
    
  2. 定义基础模型和判别器

    const mongoose = require('mongoose');
    const Schema = mongoose.Schema;
    
    const baseSchema = new Schema({
      name: String,
      createdAt: { type: Date, default: Date.now },
    }, { discriminatorKey: 'kind' });
    
    const BaseModel = mongoose.model('BaseModel', baseSchema);
    
    const ChildModel = BaseModel.discriminator('Child', new Schema({ age: Number }));
    
    module.exports = {
      BaseModel,
      ChildModel,
    };
    
  3. 在 Service 或 Controller 中使用

    const { ctx, app } = this;
    const { ChildModel } = app.model;
    
    async createChild() {
      const child = new ChildModel({ name: 'John Doe', age: 10 });
      await child.save();
      ctx.body = child;
    }
    

这样,你就可以在同一个集合中存储 BaseModelChildModel 的文档,并通过 kind 字段区分它们。判别器是处理多态关联的强大工具,适用于需要在单个集合中存储多种文档类型的情况。

回到顶部