猫鼬:findOneAndUpdate查找比_id更复杂的表达式

时间:2018-06-29 10:37:58

标签: node.js mongodb mongoose aggregation-framework insert-update

我想找到一个与某些计算出的ID匹配的文档,然后查看时间戳是否小于15分钟。如果是这样,并且找到了文档,我想使用req.body更新文档。否则,如果时间超过15分钟,或者找不到文档,我想使用req.body创建一个新文档。

现在我的问题是,我应该使用静态的findOneAndUpdate方法还是出于我的目的而太不灵活? 我正在使用聚合框架,它可以做那些类型的事情,例如更新字段和/或设置字段(如果它们尚不存在)吗? 这是我的汇总管道,用于查找文档ID和时间戳(少于15分钟):

exports.calcID = function(req,res) {
        console.log("Call aggregation stage..:")        

        Flex.aggregate([        
            {
                $addFields: {
                    subID:  {
                        "$eq": [{"$trunc": {"$divide": ["$_id", 1000000]}}, +req.params.demo_id]                    
                    },
                    rightTime: {
                        "$gte": ["$createdAt", new Date(+new Date()- 60*1000*15)]
                    }
                }
            },      
            {
                "$match": { 
                    subID:true,
                    rightTime:true

                }
            },
            {
                "$sort": {"Timestamp":-1}
            },
            {
                "$limit": 1
            },
            {
                "$project": {subID:0, rightTime:0}
            }
        ]).exec(function(err, flPot) {
            console.log(flPot);
            console.log("Anzahl gefundener Dokumente: ", flPot.length)      
            if (flPot.length == 0) {
                res.end("Keine Dokumente juenger 15 Minuten gefunden!")
                var flex = new FlexPotenzial(req.body);     
                flex.save(function(err) {
                if (err) {
                    console.log(err);
                    res.status(400);
                    res.send(err);
                }
                else {              
                    console.log("Instanz FlexPotenzial in Datenbank erzeugt!");
                    res.status(200);
                    res.json({ message: 'FlexPotenzial-Instance created in datbase!\n', flex });
                }
                })
            }
            else if (flPot.lengh!==0) {
                    flPot.Timestamp = req.body.Timestamp;
                    flPot.aktThErzeugungsleistungWaerme = req.body.aktThErzeugungsleistungWaerme;
                    flPot.aktThNachfrageleistungWaerme = req.body.aktThNachfrageleistungWaerme;
                    flPot.aktThErzeugungsleistungGas = req.body.aktThErzeugungsleistungGas;
                    flPot.aktThNachfrageleistungGas = req.body.aktThNachfrageleistungGas;
                    flPot.aktLeistungsuntergrenze = req.body.aktLeistungsuntergrenze;
                    flPot.aktLeistungsobergrenze = req.body.aktLeistungsobergrenze;
                    flPot.BrennRohstoffbezug = req.body.BrennRohstoffbezug;
                    flPot.Produktstrom = req.body.Produktstrom;
                    flPot.Dummy1 = req.body.Dummy1;
                    flPot.Dummy2 = req.body.Dummy2;
                    flPot.Dummy3 = req.body.Dummy3;
                    flPot.Dummy4 = req.body.Dummy4;

                    flPot.save(function(err) {
                        if (err) {
                            console.log(err);
                            res.status(400);
                            res.send(err);
                        }
                        else {              
                            console.log("FlexPotenzial aggregierte Daten in Datenbank aktualisiert!");
                            res.status(200);
                            res.json({ message: 'FlexPotenzial-Instance aggregated data updated!\n', flex });
                        }
                    }
                )
            }
        });
    }

我不知道什么是最好的方法,以及如何在找到或未找到文档后进行检查,如何更新字段以及是否未找到文档,如何以聚合方式或在单独的函数中创建新文档? ...

1 个答案:

答案 0 :(得分:1)

我假设您将存储的ID划分为ID范围。为什么不在查询中这样做:

const minID = req.params.demo_id * 1000000;
const maxID = (req.params.demo_id + 1) * 1000000;
const fifteenMinutesAgo = new Date(Date.now() - 15*3600*1000)
Flex.findOneAndUpdate({
  _id: { $gte: minID, $lt: maxID },
  createdAt: { $gte: fifteenMinutesAgo }
}, { $set: req.body })

当然,您应该清理输入内容,而不仅仅是投入req.body

如果ID的计算比您在此代码段中的计算复杂,请考虑将其存储在文档中。