0
{
    "_id" : ObjectId("58d9084841a6168234689aee"),
    "ID" : "01",
    "data" : {
        "Type1" : {
            "value" : "ABC",
            "timestamp" : "2017-03-20 16:01:01"
            },
        "Type2" : {
            "value" : "ccc",
            "timestamp" : "2017-03-20 16:01:01"
        }
    }
}

我想使用 nodejs 使用 queryobject 从 mongodb 获取每个 TYPE 的时间戳。怎么弄,求大神帮忙。

var queryObject = url.parse(req.url,true).query;
        var mdb = db.collection("HISTORY").find({{'timestamp':{"$gte":queryObject.fromdate,"$lt" : queryObject.todate}},{"ID":1});

这是我的节点服务:

function getHistory(req,res){
    try{
        var queryObject = url.parse(req.url,true).query;
        var index=0, resultset = [];
        var db1 = db.collection("HISTORY").find({$and : [{'data.Type1.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
            {'data.Type2.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
            {'data.Type3.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
            {'data.Type4.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
            {'data.Type5.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}}
           ]},{"Ino":1,"ID":1,"data":1});
        db1.count(function(err, count) {
            console.log("count" , count);
            db1.each(function(err, doc) {
            if(doc!=null){
                var valdata=doc.alarms;
                var fields = [];
               var queryString ="SELECT field1,NAME FROM details c inner join locdetails l on c.loc_id=l.loc_id where no='"+doc.Ino+"' limit 1;";
               var dtfield1 = null;
               var dtfield2 = null;
                 connection.query(queryString, function(err,result){
                           index++;
                        if(err){
                        }else{
                            if(result.length>0)
                                {
                                     dtfield1 = result[0].field1;
                                     dtfield2 = result[0].NAME;
                                     if(dtfield1!=null){

                                         for (var x in valdata) {
                                             var dt = new Date(valdata[x].timestamp).toISOString().replace(/T/, ' ').replace(/\..+/, '');
                                             var compareDate = new Date(dt);
                                             if(compareDate.getTime()>=fromDate.getTime()&&compareDate.getTime()<=toDate.getTime()){
                                            resultset.push({"Name":dtfield1,"LName":dtfield2,"Ino":doc.Ino,"ID":doc.ID,"data":x,"datav":valdata[x].value,"Timestamp":valdata[x].timestamp});
                                        }
                                         if(index == count){
                                                res.writeHead(200, {
                                                    'Content-Type': 'application/json'
                                                });
                                                res.write(JSON.stringify(resultset));
                                                res.end();
                                            }
                                         }} }}
                    });  
                } else {
            }
        });     
        });
    }
    catch (err) {
        console.log("Exception -- ",err);
    }

}

我希望数据应该基于时间戳进行过滤,并且可以在 UI 中显示并下载显示的数据。并且过滤器应该像当前日期数据一样在 UI 中并且也基于时间过滤器。

4

2 回答 2

0

如果您想同时基于Type1.timestampand进行搜索Type2.timestamp,您应该使用$and. 如果其中一个匹配就足够了,$and您可以更改$or

db.collection("HISTORY").find({
    $and : [{'data.Type1.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
            {'data.Type2.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}}
           ]
    },
    {ID:1}, function (err, res){

});
于 2018-10-15T07:20:03.333 回答
0

您可以使用聚合来满足您的要求。

对于仅显示每个对象的最新数据值的初始列表,您可以使用以下管道 -

[
  {
    $project:{
      _id:1,
      ID:1,
      data:{ $objectToArray: "$data" }
    }
  },
  {
    $unwind:"$data"
  },
  {
    $sort:{
      "data.v.timestamp":-1
    }
  },
  {
      $group:{
          _id:{
              _id:"$_id",
              ID:"$ID"
          },
          data:{
              $first:"$data"
          }
      }
  },
  {
      $addFields:{
          data:["$data"]
        }
  },
  {
      $addFields:{
          data:{ $arrayToObject: "$data" }
      }
  }
]

聚合的结果应该给你一个这样的对象数组 -

{
    "_id" : ObjectId("5bc469c11f8e482416d6edb3"),
    "ID" : "01",
    "data" : {
        "Type2" : {
            "value" : "ccc",
            "timestamp" : ISODate("2017-03-22T16:01:01.000+06:00")
        }
    }
}

至于过滤集合以获取具有给定范围内时间戳值的数据属性的文档,可以修改上述管道以获取它

[
  {
    $project:{
      _id:1,
      ID:1,
      data:{ $objectToArray: "$data" }
    }
  },
  {
    $unwind:"$data"
  },
  {
    $sort:{
      "data.v.timestamp":-1
    }
  },
  {
      $match:{
         "data.v.timestamp":{ $gt: "start date value", $lt: "end date value"} 
      }
  },
  {
      $group:{
          _id:{
              _id:"$_id",
              ID:"$ID"
          },
          data:{
              $addToSet:"$data"
          }
      }
  },
  {
      $project:{
          _id:"$_id._id",
          ID:"$_id.ID",
          data:{ $arrayToObject: "$data" }
      }
  }
]

此聚合的结果将生成与上述对象类似的对象数组。但是这一次每个文档的数据对象将只有符合时间戳条件的属性。

希望这可以帮助。最后对您的建议是重新考虑历史集合的模式设计。因为如果简单的基于日期的查询对您来说变得很困难。您只能想象这种设计的未来可能会为您带来什么。

于 2018-10-15T07:40:24.193 回答