【问题标题】:How to extend Query object in mongoose如何在猫鼬中扩展查询对象
【发布时间】:2012-07-13 00:20:40
【问题描述】:

我正在尝试向名为“paginate”的 Query 对象添加一个链式方法。如果我将它添加到 query.js,我可以毫无问题地使用它。但是,修改其中一个核心文件并不是一个好主意。

我正在使用我发现的经过一些修改的代码,并希望它成为 Query 原型的一部分,但我没有成功让它在 Query.js 中运行。

我怎样才能做到这一点?是否有任何关于如何通过模块扩展这些核心文件的文档?我没有找到任何适合我的东西。

mongoose.Query.prototype.paginate = function(page, limit, cb) {
  var model, query, skipFrom;
  if (page == null) {
    page = 1;
  }
  if (limit == null) {
    limit = 10;
  }
  query = this;
  model = this.model;
  skipFrom = (page * limit) - limit;
  query = query.skip(skipFrom).limit(limit);
  if (cb) {
    return query.run(function(err, docs) {
      if (err) {
        return cb(err, null, null);
      } else {
        return model.count(query._conditions, function(err, total) {
          return cb(null, total, docs);
        });
      }
    });
  } else {
    throw new Error("pagination needs a callback as the third argument.");
  }
};

【问题讨论】:

    标签: javascript node.js prototype mongoose


    【解决方案1】:

    事实证明这比我预期的要容易得多。这就是我所做的,并且奏效了:

    创建了一个 paginate.js 文件:

    mongoose = require('mongoose');
    
    mongoose.Query.prototype.paginate = function(aPageStart, aLimit, aCallback) {
      var model, query;
    
      if (aLimit == null) {
        aLimit = 10;
      }
      query = this;
      model = this.model;
      query = query.skip(aPageStart).limit(aLimit);
      if (aCallback) {
        return query.run(function(aError, aDocs) {
          if (aError) {
            return aCallback(aError, null, null);
          } else {
            return model.count(query._conditions, function(aError, aTotal) {
              return aCallback(null, aTotal, aDocs);
            });
          }
        });
      } else {
        throw new Error("pagination needs a callback as the third argument.");
      }
    };
    

    只在需要的地方需要它(在本例中是我的模型)。

    然后您可以将此方法作为链的最后一个调用。

    干杯,

    马科斯。

    【讨论】:

    • 哎呀!那行得通……但是直接扩展这样的库通常被认为是肮脏的,因为库的内部可能会更改版本。通过库的简单升级,您最终可能会得到一个非常糟糕的方法。节点库因库的内部(通常是外部)大变化而臭名昭著。如果您愿意冒损坏的风险,那就开火吧,但使用“静态”可能更安全。
    【解决方案2】:

    也许你可以使用这个模块或者看看他们是如何实现它的:mongoose-paginate

    另一种解决方案是为您的架构创建一个方法,如下所示:

    Schema.statics.paginate = (page, limit, cb) ->
       ...
      return query;
    // or
    Schema.statics.paginate = (query, page, limit, cb) ->
       ...
      return query.exec();
    

    【讨论】:

    • 是的。那是另一种方式。但是我希望它成为查询对象的一部分,这样它就可以与查询中的其他方法链接起来,比如查找、排序、填充、gt、lt 等......所以例如你可以从你的模型中做到这一点(简化):this.find().gt().populate("Entity").sort().paginate(params) 等...
    【解决方案3】:

    扩展 Mongoose 模式的 API 是 plugin()。像这样定义一个简单的插件函数:

    function paginatePlugin(schema) {
      schema.query.paginate = function({ start, limit = 10 }) {
        return this.skip(start).limit(limit);
      };
    }
    

    然后将其注入到您的模型中,例如:

    fooSchema.plugin(paginatePlugin);
    

    然后使用它:

    await Foo.find().paginate({ start: 10, limit: 100 });
    

    这也允许您编写查询扩展:

    await Foo
      .find()
      .where({ bar: { $gt: 1 } })
      .sort({ bar: 1 })
      .paginate({ start: 10, limit: 100 });
    

    【讨论】:

      猜你喜欢
      • 2021-07-01
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-28
      • 2018-01-14
      相关资源
      最近更新 更多