Mongoose:是否有一种默认将lean设置为true(始终开启)的方法?

15

我有一个只读API,希望Mongoose始终使用轻量级查询

我可以在模式或连接级别上启用此功能,使其默认为true吗?


似乎不能在模式级别上应用它(http://mongoosejs.com/docs/guide.html#options),所以我怀疑你也不能在连接级别上这样做 :/ - tomahaug
1
你可以考虑直接使用 MongoDB 原生驱动程序,它总是非常高效。 - WiredPrairie
1
@WiredPrairie - 由于其他原因,这个项目需要使用mongoose,但还是谢谢你。 - k00k
1
你可以在同一个项目中使用它们。 :) - WiredPrairie
6个回答

18

最简单的方法是对 mongoose.Query 类进行猴子补丁(Monkey Patch),以添加默认的 lean 选项:

var __setOptions = mongoose.Query.prototype.setOptions;

mongoose.Query.prototype.setOptions = function(options, overwrite) {
  __setOptions.apply(this, arguments);
  if (this.options.lean == null) this.options.lean = true;
  return this;
};
Mongoose为每个查询创建mongoose.Query的新实例,setOptions调用是mongoose.Query构造的一部分。

通过修补mongoose.Query类,您将能够全局启用轻量级查询。因此,您不需要修补全部mongoose方法(例如findfindOnefindByIdfindOneAndUpdate等)。

Mongoose在内部调用中使用Query类,例如populate。它将原始Query选项传递给每个子查询,因此理论上不应该出现问题,但无论如何都要小心这种解决方案。


你的回答比我的好多了,向你致敬! - tomahaug
这不适用于node 6.7.0和mongoose 4.5.8。有任何想法为什么? - Vikas Chandra
2
在mongoose 4.5.8中,我不得不将"this.options.lean"更改为"this.mongooseOptions.lean"。 - Vikas Chandra
3
使用mongoose 5.4.9,可以通过以下方式实现:if (this.mongooseOptions().lean == null) { this.mongooseOptions({ lean: true }); } - Leon
这在TS中怎么工作?查询返回类型仍将是“文档”,因此整个类型将无用。有没有一种方法声明所有查询返回值为“LeanDocument”? - András Geiszl

2

以下是一种可能的解决方案:

当前执行查询的方式为:

Model.find().lean().exec(function (err, docs) {
    docs[0] instanceof mongoose.Document // false
});

修改Modelfind方法:

var findOriginal = Model.prototype.find;
Model.prototype.find = function() {
    return findOriginal.apply(this, arguments).lean();
}

执行查询的新方法:

Model.find().exec(function (err, docs) {
    docs[0] instanceof mongoose.Document // false
});

我没有测试过这段代码,但如果你之前尝试过在JavaScript中覆盖库功能,那么你很容易理解我的意思。


1
当然,你需要为每个模型定义执行此操作,除非你想深入挖掘Mongoose的源代码 :) - tomahaug

1

我必须像这样使用我的nestjs应用程序。它完美地为我工作。

import { Query } from 'mongoose'

Query.prototype.setOptions = function(options: any) {
  __setOptions.apply(this, arguments)
  if (!this.mongooseOptions().lean) this.mongooseOptions().lean = true
  return this
}

1
我想指出这段代码存在一个关键问题。如果用户明确将lean选项设置为false,它会将其设置为true。因此,重要的是要执行以下操作: if (!this.mongooseOptions().lean == null) 这样做的原因是只有在提供的lean选项为null或未定义时才会执行。 - swannee

0

0

请参考以上评论:

mongoose.Query.prototype.setOptions = function(options, overwrite) {
    options = Object.assign({}, options);
    if (!options.hasOwnProperty('lean')) {
        options.lean = true;
    }
    __setOptions.call(this, options, overwrite);
    return this;
};


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

0

为mongoose模型添加默认的lean选项最简单的方法是,只需添加以下三行代码。

例如:

const mongoose = require('mongoose');
const BreakTimeTrackerSchema = new mongoose.Schema({
    user_id: {
        type: Number
    },
    company_id: {
        type: Number
    },
    break_time: {
        type: Number
    }
}, {timestamps: true});

BreakTimeTrackerSchema.set('lean', true);
BreakTimeTrackerSchema.set('toObject', { virtuals: true });
BreakTimeTrackerSchema.set('toJSON', { virtuals: true });
module.exports = mongoose.model("break_time_tracker", BreakTimeTrackerSchema);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接