在同一查询中设置值的Mongo更新记录

时间:2016-09-26 18:37:35

标签: node.js mongodb express

我有一个API的目的代码,用于更新Mongo中的文档。它使用collection.update将值插入到一个部分中,然后使用另一个collection.update将这些值推送到文档中的数组中。

但是,当我运行此代码时,我会在nanevents.eventTime中获得events.endDate = null。如何修改此功能才能正常工作?也就是说,我首先将值插入runtime.,然后使用这些值推入events数组。

router.get('/stop/:id', function(req,res){
    var collection = db.get('Activity');

    //Important to use findOne here to get an object back instead of an array
    collection.findOne({_id : req.params.id }, function(err, activity){
        if (err) throw err;
        res.json(activity);
        //console.log(activity);

        collection.update({
            _id: activity._id
        },
        {
            $set: {
                    "runtime.started": false,
                    "runtime.endDate": new Date()
            } 
        },
        function(err, activity){
            if (err) throw err;
            //res.json(activity);
            console.log(activity);
        }
        );

        collection.update({
            _id: activity._id
        },
        {
            $push: {events: {
                        eventTime: ((activity.runtime.endDate - activity.runtime.startDate) / 1000),
                        startDate: activity.runtime.startDate,
                        endDate: activity.runtime.endDate
                    }
                }, 
        },
        function(err, activity){
            if (err) throw err;
            //res.json(activity);
            console.log(activity);
        }
        );

    });
});

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

我猜你要么应该使用promise还是嵌套回调,javascript是异步的,所以即使看起来第二次更新调用会在第一次调用之后,实际上它们同时被调用,因此我觉得很奇怪行为。

最好将您的数据库调用包装在promise中并应用链接。也许你想看看令人印象深刻的$ q承诺。如果您不想使用promises,则在第一次更新调用的函数内调用第二个更新方法

router.get('/stop/:id', function(req,res){
    var collection = db.get('Activity');

    //Important to use findOne here to get an object back instead of an array
    collection.findOne({_id : req.params.id }, function(err, activity){
        if (err) throw err;
        res.json(activity);
        //console.log(activity);

        collection.update({
            _id: activity._id
        },
        {
            $set: {
                    "runtime.started": false,
                    "runtime.endDate": new Date()
            } 
        },
        function(err, activity){
            if (err) throw err;
            //res.json(activity);
            console.log(activity);
            collection.update({
             _id: activity._id
            },
            {
             $push: {events: {
                        eventTime: ((activity.runtime.endDate - activity.runtime.startDate) / 1000),
                        startDate: activity.runtime.startDate,
                        endDate: activity.runtime.endDate
                    }
                }, 
        },
        function(err, activity){
            if (err) throw err;
            //res.json(activity);
            console.log(activity);
        }
        );
        }
        );

    }); });

是的看起来非常混乱,这就是为什么承诺很好。

更新,也许您可​​以尝试将更新调用合并为一个

collection.findOne({_id : req.params.id }, function(err, activity){
        if (err) throw err;
        res.json(activity);
        //console.log(activity);
         var date  = new Date();
         var duration = (date - activity.runtime.startDate)/1000;
        collection.update({
            _id: activity._id
        },
        {
            $set: {
                    "runtime.started": false,
                    "runtime.endDate": date
            },
            $push: {events: {
                        eventTime: duration,
                        startDate: activity.runtime.startDate,
                        endDate: date
                    }
                }
        },
        function(err, activity){
            if (err) throw err;
            //res.json(activity);
            console.log(activity);
    });

});