插件

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

例子

插件是一种在多个结构中重用逻辑的工具。 假设你的数据库中有多个模型,并且想要为每个模型添加 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);

我们刚刚向 GamePlayer 结构添加了最后修改的行为,并在要启动的游戏的 lastMod 路径上声明了一个索引。 对于几行代码来说还不错。

全局插件

想要为所有结构注册一个插件吗? 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);

在编译模型之前应用插件

因为许多插件依赖于 middleware,所以你应该确保应用你称为 mongoose.model()conn.model() 的插件 before。 否则,插件注册的任何中间件都不会被应用

// 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 的插件搜索网站 上找到官方支持的插件的完整列表。

社区

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