【问题标题】:Mongoose __v property - hide?Mongoose __v 属性 - 隐藏?
【发布时间】:2012-11-21 21:28:26
【问题描述】:

Mongoose 在 Schema 中添加了一个 '__v' 属性以进行版本控制 - 是否可以全局禁用此属性或将其从所有查询中全局隐藏?

【问题讨论】:

标签: mongoose


【解决方案1】:

您可以使用查询中间件从输出中排除任何字段。在你的情况下,你可以使用这个:

// '/^find/' is a regex that matches queries that start with find
// like find, findOne, findOneAndDelete, findOneAndRemove, findOneAndUpdate
schema.pre(/^find/, function(next) {
    // this keyword refers to the current query
    // select method excludes or includes fields using + and -
    this.select("-__v");
    next();
});

有关文档查找的更多信息: Middlewares select method

【讨论】:

    【解决方案2】:

    要禁用不推荐的“__v”属性,请使用versionKey schema option

    var Schema = new Schema({...}, { versionKey: false });
    

    要对所有查询隐藏它,有时可以是not what you want too,请使用select schema type option

    var Schema = new Schema({ __v: { type: Number, select: false}})
    

    【讨论】:

    • 那么如何在将 _id 和 __v 返回给用户之前删除它们?有什么我可以做的映射吗?从模式到模型的映射会删除这两个属性,从模型到模式的映射会删除一些用户不应该编辑但仍能看到的字段。
    【解决方案3】:

    是的,很简单,只需编辑里面的“schema.js”文件

    "node_modules\mongoose\lib"

    搜索"options = utils.options ({ ... versionKey: '__v'..." 并将值"__v" 更改为false

    这将更改所有发布请求。 (versionKey: '__v' => versionKey: false)

    【讨论】:

    • 这是一个糟糕的建议。
    • 您不应该更改node_modules 中的代码。这个文件夹的内容经常随着 npm install 而改变,应该添加到.gitignore。无论你写什么都会丢失。
    【解决方案4】:

    试试这个,它将从每个查询响应中删除 _v。

    // transform for sending as json
    function omitPrivate(doc, obj) {
        delete obj.__v;
        return obj;
    }
    
    // schema options
    var options = {
        toJSON: {
            transform: omitPrivate
        }
    };
    // schema
    var Schema = new Schema({...}, options);
    

    【讨论】:

      【解决方案5】:

      您可能不想禁用__v,其他答案提供了一些链接来回答您为什么不应该禁用它。

      我用这个库隐藏了__v_id

      https://www.npmjs.com/package/mongoose-hidden

      let mongooseHidden = require("mongoose-hidden")();
      
      // This will add `id` in toJSON
      yourSchema.set("toJSON", {
              virtuals: true,
          });
      
      // This will remove `_id` and `__v` 
      yourSchema.plugin(mongooseHidden);
      

      现在__v 将存在,但不会与doc.toJSON() 一起返回。

      希望对你有帮助。

      【讨论】:

      • 为什么要使用库来进行这种愚蠢的简单转换?请改为参考 JSON 或 toObject 架构选项。 toObject() 为我工作。
      • 你是对的。其他答案也推荐了同样的事情。 @NIKHILCM
      【解决方案6】:

      两种方式:

      1. {versionKey: false}

      2. 查询时,如model.findById(id).select('-__v')

      '-' 表示排除字段

      【讨论】:

        【解决方案7】:

        定义一个 toObject.transform 函数,并确保在从 mongoose 获取文档时始终调用 toObject

        var SomeSchema = new Schema({
            <some schema spec>
          } , {
            toObject: {
              transform: function (doc, ret, game) {
                delete ret.__v;
              }
            }
        });
        

        【讨论】:

        • 您也可以调用user.toObject({ versionKey: false }),这将隐藏__v 版本属性。
        • 你还需要toJSON()吗?
        • @binki 不,不需要
        【解决方案8】:

        您可以通过将versionKey 选项设置为false 来禁用架构定义中的“__v”属性。例如:

        var widgetSchema = new Schema({ ... attributes ... }, { versionKey: false });
        

        我认为您不能全局禁用它们,但只能按 Schema 执行。你可以阅读更多关于 Schema 的options here。您可能还会发现Schema set method 很有帮助。

        【讨论】:

        • 禁用“__v”属性是否安全?如果我禁用它会导致任何未来的问题吗?
        • 有没有办法从查询返回的文档中隐藏它?
        • 安全吗?您可以阅读详细信息here。 TL:博士; Mongoose 使用版本键来帮助避免位置符号遇到的错误,例如$set: { 'comments.3.body': updatedText }。如果您阅读文档并使用该更新语句,但同时有人修改了comments 数组,您可能会更新错误的评论。在这种情况下,如果使用版本密钥,您将获得异常。
        猜你喜欢
        • 1970-01-01
        • 2014-09-12
        • 1970-01-01
        • 2014-10-14
        • 1970-01-01
        • 2018-07-15
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多