【问题标题】:Mongodb aggregate $match inconsistent handling of dates between mongo and javascriptMongodb 聚合 $match 对 mongo 和 javascript 之间日期的处理不一致
【发布时间】:2016-08-09 14:35:37
【问题描述】:

我正在 mongodb shell 中进行以下聚合:

db.sensors.aggregate([
    { $match: { timestamp: {$gte: ISODate("2016-08-08T15:46:00.0Z")} } },
    { $group: { 
        _id: "$sensorId", 
        avgSensor: { $avg: "$value" }, 
        avgDuration: { $avg: "$duration"} 
    }} 
])

效果很好,并为我提供了时间戳晚于 15:46 的文档聚合。

如果我在 Node.js 中做同样的事情:

sensors.aggregate([
    { $match: { timestamp: { $gte: new Date('2016-08-08T15:46.000Z') } } },
    { $group: { 
        _id: "$sensorId", 
        avgSensor: { $avg: "$value" }, 
        avgDuration: { $avg: "$duration"} 
    }} 
], function (err,aggregate) { ...error handling stuff }

然后我得到一组不同的(错误的)数据,似乎忽略了日期并匹配所有内容。

所以我认为ISODate()Date() 没有直接可比性。知道如何解决这个问题,以便我的 javascript 工作吗?


这可能是一个线索:如果我尝试在 mongodb 中执行日期范围,它可以正常工作,但 javascript 中的日期范围返回不匹配:

sensors.aggregate([
    { $match: { timestamp: { 
        $gte: new Date('2016-08-08T15:46.000Z'), 
        $lt: new Date('2016-08-09T09:00.00Z') 
    } } }, 
    { $group: { 
        _id: "$sensorId", 
        avgSensor: { $avg: "$value" }, 
        avgDuration: { $avg: "$duration"} 
    }} 
], function (err,aggregate) { ...error handling... }

【问题讨论】:

  • 你试过用其他Date构造函数new Date(2016,7,8,15,46,0)吗?
  • new Date('2016-08-08T15:46.000Z') 返回undefined; Node.js Date 无法解析 ISO 日期。
  • 感谢@chridam 的回答。似乎使用 ISODate 格式的任何努力都行不通。

标签: node.js mongodb aggregation-framework


【解决方案1】:

非常感谢@chridam 的回答。更正后的代码(完整的工作日期范围)是:

var daystart=new Date(2016,07,08,16,46,0);
var daystop=new Date(2016,07,08,17,46,0);
sensors.aggregate([{$match: { timestamp: { $gte: daystart, $lt: daystop } } }, {$group: { _id: "$sensorId", avgSensor: { $avg: "$value" }, avgDuration: { $avg: "$duration"} }} ], function (err,aggregate) {

...错误处理...}

似乎试图在 Javascript 中使用 ISODate 是个问题。请注意,使用的 Date 构造函数对于月份来说有点奇怪——我不得不使用 07 来表示 August。

【讨论】:

  • 当使用 JavaScript Date() 构造函数时,月份参数是基于 0-index 的,即一月是 0,二月是 1 等等
【解决方案2】:

使用new Date(/*timestmap or whatever parsable value*/).toISOString()

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期性价值。 - From Review
  • 恐怕这不起作用 - 但使用 @chridam 建议的其他 Date 构造函数可以完成这项工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 2017-08-09
相关资源
最近更新 更多