【问题标题】:How to get average of one field value per min from mongo with aggregate query?如何通过聚合查询从 mongodb 获取每分钟一个字段值的平均值?
【发布时间】:2021-04-06 22:44:02
【问题描述】:

我在 MongoDb 中将数据保存为

{
  "_id": "ObjectId(\"5fec31b6b9022035abbbf7cc\")",
  "message": {
    "date": "2020-12-30 13:20:26",
    "time": "2020-12-30T07:50:26.000Z",
    "ID": "005",
    "P": 1.36
  }
},
{
  "_id": "ObjectId(\"5fec31b5b9022035abbbf7c2\")",
  "message": {
    "date": "2020-12-30 13:20:24",
    "time": "2020-12-30T07:50:24.000Z",
    "ID": "005",
    "P": 1.5
  }
 
},
{
  "_id": "ObjectId(\"5fec31b0b9022035abbbf7b3\")",
  "message": {
    "date": "2020-12-30 13:20:19",
    "time": "2020-12-30T07:50:19.000Z",
    "ID": "005",
    "P": 1.63
  }
  
}

我想找到每分钟 P 值的平均值。 我试过Group result by 15 minutes time interval in MongoDb 但我在时间字段中遇到了错误。

db.pressure.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "message.time" },
      "dayOfYear": { "$dayOfYear": "message.time" },
      "hour": { "$hour": "message.time" },
      "interval": {
        "$subtract": [ 
          { "$minute": "message.time" },
          { "$mod": [{ "$minute": "message.time"}, 1] }
        ]
      }
    },
      
  
    "count": { "$sum": 1 }
  }
  }
  
])

{ "message" : "无法从 BSON 类型字符串转换为日期", “好”:0, “代码”:16006, "codeName" : "Location16006", “名称”:“MongoError” }

【问题讨论】:

  • 将日期/时间值存储为 string 是一个设计缺陷。始终使用正确的 Date 对象 - 然后您的聚合管道将起作用。

标签: node.js mongodb aggregation-framework


【解决方案1】:

一些修复:

  • 您需要使用 $toDate 将字符串日期转换为日期类型(来自 MongoDB 4.0)$addFields 会将 message.time 字段更新为日期类型
  • $year, $hour 等运算符需要使用 $ 符号引用字段,您在 message.time 中错过了它
  • 使用$avg 得到message.P 的平均值
db.collection.aggregate([
  { $addFields: { "message.time": { $toDate: "$message.time" } } },
  {
    "$group": {
      "_id": {
        "year": { "$year": "$message.time" },
        "dayOfYear": { "$dayOfYear": "$message.time" },
        "hour": { "$hour": "$message.time" },
        "interval": {
          "$subtract": [
            { "$minute": "$message.time" },
            { "$mod": [{ "$minute": "$message.time" }, 15] }
          ]
        }
      },
      "count": { "$count": 1 },
      "average": { "$avg": "$message.P" }
    }
  }
])

Playground


MongoDB 3.6:您可以使用$dateFromString

  {
    $addFields: {
      "message.time": {
        $dateFromString: { dateString: "$message.time" }
      }
    }
  }

Playground

【讨论】:

  • "time": "2020-12-30T07:50:24.000Z",是这种类型的字符串。但是在 mongo 中它显示为日期类型
  • { "message" : "无法识别的表达式 '$toDate'", "ok" : 0, "code" : 168, "codeName" : "InvalidPipelineOperator", "name" : "MongoError" }
  • 你的mongodb是什么版本的?
  • 我认为它是 3.6
  • $toDate 来自 mongodb v4.0 我为 3.6 添加了另一个选项,它是 $dateFromString
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
相关资源
最近更新 更多