使用javascript试图将UTC字符串日期转换为Date对象的MongoDB中的聚合查询

时间:2018-05-15 20:21:16

标签: javascript mongodb meteor minimongo

我正在尝试按小时对日期时间进行分组,我正在从json文件上传数据。但是日期时间是UTC格式的字符串。如何在meteor中使用javascript将它们转换为Date对象?

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

指标已采用UTC格式。

这是一份文件。

{
    "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"
  }

1 个答案:

答案 0 :(得分:2)

如果“字符串”与"2018-05-15T20:59:31.502Z"中的“词汇”ISO格式一样,那么您“可以”获取$substr部分:

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

如果您有MongoDB 3.6可用,那么您“可以”使用$dateFromString实际将其转换为BSON日期格式,但您可能希望以类似的方式截断该字符串,以实现您实际想要的任何日期舍入:

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

MongoDB 4.0的$toDate缩短了一点,并进行了相同的BSON日期转换:

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

但基本的事实是,如果你的“字符串”实际上看起来并不是那样,并且不能真正被支持的运营商以一致的方式分解成字符串的一部分,那么你通常会更好地转换存储在你的字符串中的日期集合首先是实际的BSON日期。

这里要做的“推荐”事实是实际运行数据转换。 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 = [];
}

这是基本过程。当然,如果您的“字符串”不是ISO格式或任何适合传递给Date()进行转换的话,那么您实际上需要采取其他措施。

至少BSON Date是一个带有“内部”数字表示的8-btye数据结构,其中作为等效的“字符串”,它至少为24字节,甚至更长的单词命名日期和月份。在使用数据库时,保持本质上基本上是“数字”的数据是有意义的。

我的建议是转换数据,并且可能在导入时,或者如果你无法工作,那么至少一次加载到集合中。尝试使用字符串来处理他们真正不想做的事情会更好。

  

注意 $substr被视为已弃用,实际上现在为$substrBytes别名,或者您可以使用$substrCP,具体取决于数据的实际编码。 3.2之前的旧版MongoDB只有$substr表达式。