插件
模式是可插拔的,也就是说,它们允许应用预先打包的功能来扩展其功能。这是一个非常强大的功能。
示例
插件是用于在多个模式中重用逻辑的工具。假设您的数据库中有几个模型,并且想要为每个模型添加一个loadedAt
属性。只需创建一个插件,并将其应用于每个Schema
// loadedAt.js
module.exports = function loadedAtPlugin(schema, options) {
schema.virtual('loadedAt').
get(function() { return this._loadedAt; }).
set(function(v) { this._loadedAt = v; });
schema.post(['find', 'findOne'], function(docs) {
if (!Array.isArray(docs)) {
docs = [docs];
}
const now = new Date();
for (const doc of docs) {
doc.loadedAt = now;
}
});
};
// game-schema.js
const loadedAtPlugin = require('./loadedAt');
const gameSchema = new Schema({ /* ... */ });
gameSchema.plugin(loadedAtPlugin);
// player-schema.js
const loadedAtPlugin = require('./loadedAt');
const playerSchema = new Schema({ /* ... */ });
playerSchema.plugin(loadedAtPlugin);
我们刚刚为Game
和Player
模式添加了加载时间行为,并在Games
的loadedAt
路径上声明了一个索引。对于几行代码来说还不错。
全局插件
想要为所有模式注册一个插件吗?Mongoose 单例有一个.plugin()
函数,可以为每个模式注册一个插件。例如
const mongoose = require('mongoose');
mongoose.plugin(require('./loadedAt'));
const gameSchema = new Schema({ /* ... */ });
const playerSchema = new Schema({ /* ... */ });
// `loadedAtPlugin` gets attached to both schemas
const Game = mongoose.model('Game', gameSchema);
const Player = mongoose.model('Player', playerSchema);
在编译模型之前应用插件
由于许多插件依赖于中间件,因此您应该确保在调用mongoose.model()
或conn.model()
之前应用插件。否则,插件注册的任何中间件都不会应用.
// loadedAt.js
module.exports = function loadedAtPlugin(schema, options) {
schema.virtual('loadedAt').
get(function() { return this._loadedAt; }).
set(function(v) { this._loadedAt = v; });
schema.post(['find', 'findOne'], function(docs) {
if (!Array.isArray(docs)) {
docs = [docs];
}
const now = new Date();
for (const doc of docs) {
doc.loadedAt = now;
}
});
};
// game-schema.js
const loadedAtPlugin = require('./loadedAt');
const gameSchema = new Schema({ /* ... */ });
const Game = mongoose.model('Game', gameSchema);
// `find()` and `findOne()` hooks from `loadedAtPlugin()` won't get applied
// because `mongoose.model()` was already called!
gameSchema.plugin(loadedAtPlugin);
官方支持的插件
Mongoose 团队维护着一些插件,这些插件为 Mongoose 添加了很酷的新功能。以下是一些示例
- mongoose-autopopulate:始终在您的 Mongoose 模式中
populate()
某些字段。 - mongoose-lean-virtuals:使用
.lean()
时,将虚拟属性附加到 Mongoose 查询的结果。 - mongoose-cast-aggregation
您可以在Mongoose 的插件搜索网站上找到官方支持插件的完整列表。
社区
您不仅可以在自己的项目中重用模式功能,而且还可以从 Mongoose 社区中获益。发布到npm的任何插件,并且带有'mongoose'作为npm 关键字,都会显示在我们的搜索结果页面上。