Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Mongoose findByIdAndUpdate未对子文档运行验证_Node.js_Mongoose - Fatal编程技术网

Node.js Mongoose findByIdAndUpdate未对子文档运行验证

Node.js Mongoose findByIdAndUpdate未对子文档运行验证,node.js,mongoose,Node.js,Mongoose,这是我的模型: 'use strict'; var nested = new Schema({ name: String }); var test = new Schema({ url : { type : String, // First validation validate : [validator.isURL, 'Invalid URL'] }, array : [ {

这是我的模型:

'use strict';
var nested = new Schema({
    name: String
});

var test = new Schema({
    url   : {
        type      : String,
        // First validation
        validate  : [validator.isURL, 'Invalid URL']
    },
    array : [
        {
            type: nested,

            // Second Validation
            validate: [function(value) {console.log("CALLED"); return value.length <=3;}, 'Too long']
        }
    ]
});

module.exports = Parent.discriminator('Test', test);;
以下是最新消息:

Test.findByIdAndUpdate(id, {$set: {array: whatever}}, {new: true, runValidators: true}, function(err, model) {
    if (err) {
        return res.status(422).json(err);
    }

    res.status(200).json(model);
});
假设
无论什么
在两种情况下都包含长度为4的数组(新建和更新)

当创建一个新模型时,两个验证都按预期工作,我得到一个错误。但是,当使用
findbyidanddupdate
时,只运行第一次验证,忽略
array
属性上的验证(甚至不调用)。给出了什么?

根据,如果
runValidators
设置为true,则验证器似乎仅适用于
update()
findOneAndUpdate()

您是否尝试过:

Test.findOneAndUpdate({_id: id}, {$set: {array: whatever}}, {new: true, runValidators: true}, function(err, model) {
    if (err) {
        return res.status(422).json(err);
    }

    res.status(200).json(model);
});

验证程序在findByIdAndUpdate上不起作用(不确定,但在我的情况下不起作用),您可以使用中间件来摆脱验证程序,但需要编写一些额外的代码

中间件将如下所示

[SCHEMA].pre('findOneAndUpdate', function(next){
    // findOneAndUpdate and findByIdAndUpdate, will fire this hook

    console.log(this.getUpdate()); // it will return the update Object
    console.log(this.getQuery());  // it will return the query object
    // Do all validation here and modify the update object
    // this.getUpdate().url = 'stackoverflow.com';

    // for sub-docs you need to use loop;
    if(this.getUpdate() && Array.isArray(this.getUpdate().array))
        this.getUpdate().array = this.getUpdate().array.map(function(val){
            return (val.length <= 3) ? true : 'To Long';
        }); 

    // after all validation call next
    next();
});
[SCHEMA].pre('findOneAndUpdate',函数(下一个){
//findOneAndUpdate和FindByAndUpdate将触发此钩子
console.log(this.getUpdate());//它将返回更新对象
console.log(this.getQuery());//它将返回查询对象
//在此处执行所有验证并修改更新对象
//this.getUpdate().url='stackoverflow.com';
//对于子文档,您需要使用循环;
if(this.getUpdate()&&Array.isArray(this.getUpdate().Array))
this.getUpdate().array=this.getUpdate().array.map(函数(val){

return(val.length不是在文档中解释的吗?findByIdAndUpdate忽略验证和钩子?(默认值、setter、验证程序和中间件都被忽略)它甚至运行了第一个验证器,这有点让人吃惊。@KevinB确实如此。
runValidators
选项默认设置为
false
,但我在代码中将其设置为
true
,这可能允许运行第一个验证器,但不允许运行第二个(子文档上的一个)。它在我的模型上运行几乎所有的验证器,除了子文档数组上的验证器。有更好的方法吗?我需要通过PUT(实际上是补丁)更新我的文档,我能看到的另一种选择是使用
find
,然后使用
save
,这使得
findbyiandupdate
的目的让我很困惑。如果使用
$set
,那么
this.getUpdate()
将给出这样的对象
{$set:{array:[]}
[SCHEMA].pre('findOneAndUpdate', function(next){
    // findOneAndUpdate and findByIdAndUpdate, will fire this hook

    console.log(this.getUpdate()); // it will return the update Object
    console.log(this.getQuery());  // it will return the query object
    // Do all validation here and modify the update object
    // this.getUpdate().url = 'stackoverflow.com';

    // for sub-docs you need to use loop;
    if(this.getUpdate() && Array.isArray(this.getUpdate().array))
        this.getUpdate().array = this.getUpdate().array.map(function(val){
            return (val.length <= 3) ? true : 'To Long';
        }); 

    // after all validation call next
    next();
});