简体   繁体   English

使用JavaScript尝试在MongoDB中汇总查询,尝试将UTC字符串日期转换为Date对象

[英]Aggregate query in MongoDB using javascript trying to convert UTC string date to Date object

I'm trying to group datetimes by the hour and I am uploading data from a json file. 我正在尝试按小时对日期时间进行分组,并且正在从json文件上传数据。 The datetimes are in UTC format as strings though. 尽管日期时间采用字符串形式的UTC格式。 How do I convert them to Date objects using javascript in meteor? 如何使用流星中的javascript将它们转换为Date对象?

var data = Subjects.aggregate([{$match: no_null},
                  { $project: 
                    { bin: { $hour: new Date("$metrics."+metric") } 
                  } },
                  {$group: { _id: "$bin", count: {$sum: 1} } } ])

Metric is already in UTC format. 指标已采用UTC格式。

Here is one document. 这是一个文件。

{
    "metrics": {
      "ACT_04": 3.733333333, 
      "ACT_05": 14.5, 
      "ACT_02": "1970-01-01T05:02:30Z", 
      "ACT_03": 7.0833333329999997, 
      "ACT_01": "1970-01-01T20:03:00Z"
    }, 
    "subject_id": "M10965219", 
    "name": "sub-M10965219_Act"
  }

If the "string" is in "lexical" ISO Format as in "2018-05-15T20:59:31.502Z" , then you "could" get the $substr parts: 如果“字符串”采用“词汇” ISO格式(如"2018-05-15T20:59:31.502Z" ,则“可以”获得$substr部分:

Subjects.aggregate([
  { "$group": {
    "_id": { "$substr": ["$metrics."+metric,0,10] },
    "count": { "$sum": 1 }
  }}
])

If you have MongoDB 3.6 available then you "could" use $dateFromString to actually get that into a BSON date format, but you probably want to similarly truncate that string in a similar way for any date rounding you actually want: 如果您有可用的MongoDB 3.6,则可以“使用” $dateFromString将其实际转换为BSON日期格式,但是对于实际需要的任何日期舍入,您可能希望以类似的方式截断该字符串:

Subjects.aggregate([
  { "$group": {
    "_id": {
      "$dateFromString": {
        "dateString": { "$substr": ["$metrics."+metric,0,10] }
      }            
    },
    "count": { "$sum": 1 }
  }}
])

MongoDB 4.0 has $toDate for a little shorter and does the same BSON Date conversion: MongoDB 4.0的$toDate短了一点,并且执行了相同的BSON日期转换:

Subjects.aggregate([
  { "$group": {
    "_id": {
      "$toDate": { "$substr": ["$metrics."+metric,0,10] }
    },
    "count": { "$sum": 1 }
  }}
])

But the basic fact this if your "string" does not actually look like that and cannot really be broken into parts of the string in a consistent way by supported operators, then you are generally far better off converting the dates stored in your collection(s) to be actual BSON Dates in the first place. 但基本事实是,如果您的“字符串”实际上看起来不是这样,并且不能真正地被支持的运算符以一致的方式分解为字符串的各个部分,那么通常最好转换存储在集合中的日期)首先是实际的BSON日期。

The "recommended" thing to do here is instead to actually run the conversion of the data. 这里要做的“建议”是实际运行数据转换。 The mongo shell should be sufficient to run "one-off" conversions: mongo shell应该足以运行“一次性”转换:

var batch = [];

db.subjects.find().forEach(doc => {

  var fields = Object.keys(doc.metrics).map(k => ({
    ['metrics.'+k]: new Date(doc.metrics[k]),
  })).reduce((acc,curr) => Object.assign(acc,curr),{});

  batch.push({
    "updateOne": {
      "filter": doc._id",
      "update": { "$set": fields }
    }
  });

  if ( batch.length > 1000 ) {
     db.subjects.bulkWrite(batch);
     batch = []
  }
})

if ( batch.length > 0 ) {
  db.subjects.bulkWrite(batch);
  batch = [];
}

That's the basic process. 这是基本过程。 Of course if your "strings" are not in an ISO Format or any suitable for passing to Date() for conversion, then you'll actually need to take other measures. 当然,如果您的“字符串”不是ISO格式或任何适合传递给Date()进行转换的格式,则实际上您需要采取其他措施。

At the very least a BSON Date is is an 8-btye data structure with an "internal" numeric representation, where as the equivalent "string" it at least 24-bytes and even longer with words naming days and months. 至少BSON日期是一个8字节的数据结构,带有“内部”数字表示形式,其中与之等效的“字符串”至少24字节,甚至更长,并且使用命名日期和月份的单词。 It makes sense to keep data that is essentially "numeric" in nature in that form when working with a database. 在使用数据库时,将本质上本质上为“数字”的数据保留为这种形式是有意义的。

My advice is to convert the data, and possibly on import or if you cannot work that out then at least once loaded to the collection. 我的建议是转换数据,并可能在导入时转换,或者如果无法进行转换,则至少将其加载到集合中。 It's better that trying to work with strings for something they are really not meant to do. 最好尝试使用字符串来完成实际上不应该做的事情。

Note $substr is considered deprecated and actually now aliases $substrBytes , or you can use $substrCP depending on the actual encoding of the data. 注意 $substr被认为已弃用,实际上现在是$substrBytes别名,或者您可以根据数据的实际编码使用$substrCP Older MongoDB releases before 3.2 have the $substr expression only. MongoDB 3.2之前的旧版本仅具有$substr表达式。

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

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