插件

¥Plugins

结构是可插入的,也就是说,它们允许应用预先打包的功能来扩展其功能。这是一个非常强大的功能。

¥Schemas are pluggable, that is, they allow for applying pre-packaged capabilities to extend their functionality. This is a very powerful feature.

示例

插件是一种在多个结构中重用逻辑的工具。假设你的数据库中有多个模型,并且想要为每个模型添加 loadedAt 属性。只需创建一个插件一次并将其应用到每个 Schema

¥Plugins are a tool for reusing logic in multiple schemas. Suppose you have several models in your database and want to add a loadedAt property to each one. Just create a plugin once and apply it to each 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);

我们刚刚向 GamePlayer 模式添加了加载时行为,并在要启动的游戏的 loadedAt 路径上声明了一个索引。对于几行代码来说还不错。

¥We just added loaded-time behavior to both our Game and Player schemas and declared an index on the loadedAt path of our Games to boot. Not bad for a few lines of code.

全局插件

想要为所有结构注册一个插件吗?mongoose 单例有一个 .plugin() 函数,可以为每个结构注册一个插件。例如:

¥Want to register a plugin for all schemas? The mongoose singleton has a .plugin() function that registers a plugin for every schema. For example:

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() 之前应用插件。否则,插件注册的任何中间件都不会被应用

¥Because many plugins rely on middleware, you should make sure to apply plugins before you call mongoose.model() or conn.model(). Otherwise, any middleware the plugin registers won't get applied.

// 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 添加了很酷的新功能。这是几个:

¥The Mongoose team maintains several plugins that add cool new features to Mongoose. Here's a couple:

你可以在 Mongoose 的插件搜索网站 上找到官方支持的插件的完整列表。

¥You can find a full list of officially supported plugins on Mongoose's plugins search site.

社区

¥Community

你不仅可以在自己的项目中重用结构功能,还可以从 Mongoose 社区中获益。任何发布到 npm 且 'mongoose' 作为 npm 关键字 的插件都会显示在我们的 搜索结果 页面上。

¥Not only can you re-use schema functionality in your own projects, but you also reap the benefits of the Mongoose community as well. Any plugin published to npm and with 'mongoose' as an npm keyword will show up on our search results page.