插件

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

示例

插件是用于在多个模式中重用逻辑的工具。假设您的数据库中有几个模型,并且想要为每个模型添加一个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模式添加了加载时间行为,并在GamesloadedAt路径上声明了一个索引。对于几行代码来说还不错。

全局插件

想要为所有模式注册一个插件吗?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 的插件搜索网站上找到官方支持插件的完整列表。

社区

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