Mongoose是否实际验证了对象ID的存在?

时间:2013-08-29 16:44:08

标签: mongodb mongoose

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

6 个答案:

答案 0 :(得分:20)

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

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');

答案 1 :(得分:11)

我正在使用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);

答案 2 :(得分:3)

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

答案 3 :(得分:1)

您可以尝试https://www.npmjs.com/package/lackey-mongoose-ref-validator(我是开发人员)

如果在其他文档上使用引用,它也会阻止删除。

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

这是一个早期版本,因此预计会出现一些错误。如果您发现任何票,请填写。

答案 4 :(得分:0)

我发现此线程非常有用,这是我想出的:

我编写了这个中间件(无论如何我还是想让它知道),我写了检查引用模型以获取字段中提供的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);

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

答案 5 :(得分:0)

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

例如,在一个简单的“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');