【问题标题】:Does Mongoose Actually Validate the Existence of An Object Id?Mongoose 是否真的验证了对象 ID 的存在?
【发布时间】:2013-09-02 05:18:39
【问题描述】:

我喜欢 Mongoose 附带的验证功能。我们试图弄清楚我们是否要使用它,并忍受开销。有谁知道在创建 mongoose 模式时是否提供对父集合的引用(在子模式中,将父对象的对象 ID 指定为字段),这是否意味着每次您尝试保存文档时检查父集合是否存在引用的对象 ID?

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    不,在您的架构中定义为对另一个集合的引用的 ObjectId 字段在保存时不会检查为存在于引用的集合中。如果需要,您可以在 Mongoose 中间件中执行此操作。

    【讨论】:

    • 有道理。假设我们正确编码并且不会输入不存在的对象ID,我们将提高性能。这当然有其自身的风险,但我们正在从 java 重写为 node 以匹配我们架构的其余部分,并希望解决我们遇到的一些严重的性能问题。
    【解决方案2】:

    我正在使用中间件,在验证时执行元素搜索:

    ExampleSchema = new mongoose.Schema({
    
        parentId: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Example'
        }
    
    });
    
    ExampleModel = mongoose.model('Example', ExampleSchema);
    
    ExampleSchema.path('parentId').validate(function (value, respond) {
    
        ExampleModel.findOne({_id: value}, function (err, doc) {
            if (err || !doc) {
                respond(false);
            } else {
                respond(true);
            }
        });
    
    }, 'Example non existent');
    

    【讨论】:

    【解决方案3】:

    我正在使用mongoose-id-validator。效果不错

    var mongoose = require('mongoose');
    var idValidator = require('mongoose-id-validator');
    
    var ReferencedModel = new mongoose.Schema({name: String});
    
    var MySchema = new mongoose.Schema({
      referencedObj : { type: mongoose.Schema.Types.ObjectId, ref: 'ReferencedModel'},
      referencedObjArray: [{ type: mongoose.Schema.Types.ObjectId, ref: 'ReferencedModel' }]
    });
    
    MySchema.plugin(idValidator);
    

    【讨论】:

    • 我喜欢这样。漂亮而简单。
    • 最后一次发布是在 16 天前。到今天还在更新,不错!
    【解决方案4】:

    你可以试试https://www.npmjs.com/package/lackey-mongoose-ref-validator(我是开发者)

    如果引用用于另一个文档,它还可以防止删除。

    var mongooseRefValidator = require('lackey-mongoose-ref-validator');
    mongoSchema.plugin(mongooseRefValidator, {
        onDeleteRestrict: ['tags']
    });
    

    这是一个早期版本,所以预计会有一些错误。找到的话就填一张票。

    【讨论】:

      【解决方案5】:

      我发现这个帖子很有帮助,这就是我想出的:

      这个中间件(我认为它是一个,如果不是,请告诉我)我写的检查引用模型的字段中提供的 id。

      const mongoose = require('mongoose');
      
      module.exports = (value, respond, modelName) => {
          return modelName
              .countDocuments({ _id: value })
              .exec()
              .then(function(count) {
                  return count > 0;
              })
              .catch(function(err) {
                  throw err;
              });
      }; 
      

      示例模型:

      const mongoose = require('mongoose');
      const uniqueValidator = require('mongoose-unique-validator');
      const Schema = mongoose.Schema;
      const User = require('./User');
      const Cart = require('./Cart');
      const refIsValid = require('../middleware/refIsValid');
      
      const orderSchema = new Schema({
          name: { type: String, default: Date.now, unique: true },
          customerRef: { type: Schema.Types.ObjectId, required: true },
          cartRef: { type: Schema.Types.ObjectId, ref: 'Cart', required: true },
          total: { type: Number, default: 0 },
          city: { type: String, required: true },
          street: { type: String, required: true },
          deliveryDate: { type: Date, required: true },
          dateCreated: { type: Date, default: Date.now() },
          ccLastDigits: { type: String, required: true },
      });
      
      orderSchema.path('customerRef').validate((value, respond) => {
          return refIsValid(value, respond, User);
      }, 'Invalid customerRef.');
      
      orderSchema.path('cartRef').validate((value, respond) => {
          return refIsValid(value, respond, Cart);
      }, 'Invalid cartRef.');
      
      orderSchema.path('ccLastDigits').validate(function(field) {
          return field && field.length === 4;
      }, 'Invalid ccLastDigits: must be 4 characters');
      
      orderSchema.plugin(uniqueValidator);
      
      module.exports = mongoose.model('order', orderSchema);
      

      我是一个非常新的开发人员,因此非常重视任何反馈!

      【讨论】:

      • 太棒了!这对我来说非常有效。
      • 注意:这仅在编写ObjectId 时验证关系的存在。这并不能确保关系在以后不会被删除。
      【解决方案6】:

      我知道这是一个旧线程,但我遇到了同样的问题,我想出了一个更“现代”的解决方案。 我自己不是专家,希望我不会误导任何人,但这似乎有效:

      例如,在一个简单的“notes”模式中,它包含一个用户字段:

      const noteSchema = new Schema({
        user: { type: Schema.Types.ObjectId, ref: 'User' },
        text: String
      });
      

      这是检查 userId 是否存在的中间件:

      noteSchema.path('user').validate(async (value) => {
        return await User.findById(value);
      }, 'User does not exist');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-25
        • 2021-04-24
        • 1970-01-01
        • 1970-01-01
        • 2014-06-08
        • 2021-10-01
        相关资源
        最近更新 更多