Nodejs egg-mongoose 的写法怎么实现 Discriminators?
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
在 Node.js 中使用 egg-mongoose
实现 Mongoose 的 Discriminators(判别器),可以让你在同一个集合中存储多种模型类型。以下是一个简单的实现示例:
首先,确保你已经安装了 mongoose
和 egg-mongoose
插件。
-
配置
egg-mongoose
: 在config/plugin.js
中启用mongoose
插件:exports.mongoose = { enable: true, package: 'egg-mongoose', };
-
定义基础模型和判别器:
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, };
-
在 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; }
这样,你就可以在同一个集合中存储 BaseModel
和 ChildModel
的文档,并通过 kind
字段区分它们。判别器是处理多态关联的强大工具,适用于需要在单个集合中存储多种文档类型的情况。