简体   繁体   English

猫鼬批量保存/更新与异步每个只更新一些文档

[英]Mongoose batch save/update with async each only updates some docs

I have a batch update that I am trying to perform using the contents of a user-submitted form. 我有一个批处理更新,我正在尝试使用用户提交的表单的内容执行该更新。 Each submission updates a variable subset of the submitted docs. 每个提交都会更新提交文档的可变子集。 It seems like the final callback is basically being called before all the async operations complete, but I cannot figure out how to resolve it. 似乎基本上在所有异步操作完成之前就调用了最终回调,但是我不知道如何解决它。 I also tried this with async.eachSeries but the error is the same. 我也用async.eachSeries尝试过,但是错误是相同的。

    // updates is a list of object ids    
    Items.model.find ({
        _id: {$in: updates}
    })
        .exec (function (err, found) {
            console.log (found);
            // 'found' contains the expected submissions
            for (var i = 0; i < found.length; i++) {
                console.log (found [i]._id);
                found [i].category = ObjectId (req.body [found [i]._id]);
                found [i].state = 'submitted';
            }

            // 'found' now shows the desired updates correctly
            console.log (found);
            async.eachSeries (found, function (item, next) {
                console.log (item);
                //each item appears to contain the desired updates
                item.save (function (err) {
                    if (err) return next (err);
                    return next ();
                });
            }, function (err) {
                console.log (err);
                console.log ("done");
                return res.redirect ('/dataview/' + locals.app.name + "/" + req.body.page);
            });
        });

at the end of all the above, if we revisit the page, only a subset of the docs is actually updated and stored apparently. 在上述所有操作的最后,如果我们重新访问该页面,则实际上只有文档的一个子集实际上得到了更新和存储。 I'm tearing my hair out trying to figure out why. 我正在拔头发试图找出原因。

You can use async.eachOfSeries to complete in single iteration instead of double 您可以使用async.eachOfSeries以单次迭代而不是双次完成

// updates is a list of object ids    
Items.model.find({
        _id: {
            $in: updates
        }
    })
    .exec(function (err, found) {
        console.log(found);
        // 'found' contains the expected submissions
        async.eachOfSeries(found, function (item, i, next) {
            item.category = ObjectId(req.body[item._id]);
            item.state = 'submitted';
            console.log(item);
            //each item appears to contain the desired updates
            item.save(next);
        }, function (err) {
            console.log(err);
            console.log("done");
            return res.redirect('/dataview/' + locals.app.name + "/" + req.body.page);
        });
    });

But I would like to recommend you to use Promise.all function and update directly rather than find and update 但我建议您使用Promise.all函数直接更新而不是查找和更新

const itemList = [];
for (var i = 0; i < updates.length; i++) {
    itemList.push(Items.model.update({
        _id: updates[i]
    }, {
        $set: {
            state: 'submitted',
            category: ObjectId(req.body[updates[i]])
        }
    }));
}
Promise.all(itemList)
    .then((items) => {
        console.log('success');
        return res.redirect('/dataview/' + locals.app.name + '/' + req.body.page);
    })
    .catch((err) => {
        console.log('error ', err);
        return res.redirect('/dataview/' + locals.app.name + '/' + req.body.page);
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM