18

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

4

6 回答 6

23

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

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');
于 2013-11-20T03:15:44.857 回答
17

我正在使用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);
于 2014-12-13T17:37:27.247 回答
3

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

于 2013-08-29T17:23:15.237 回答
1

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

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

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

这是一个早期版本,因此预计会有一些错误。如果您发现任何问题,只需填写一张票。

于 2015-09-01T11:52:46.693 回答
1

我发现这个线程非常有帮助,这就是我想出的:

我编写的这个中间件(我认为它是一个,如果不是,请告诉我)检查引用模型以获取字段中提供的 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);

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

于 2019-12-09T19:20:59.047 回答
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');
于 2021-07-27T18:00:10.803 回答