【问题标题】:Mongoose query for documents from last 24 hours, only one document per hourMongoose 查询过去 24 小时内的文档,每小时仅一份文档
【发布时间】:2018-06-22 23:20:39
【问题描述】:

我正在编写一个应用程序,其中有一些天气传感器,每 5 分钟将空气的温度和湿度发送到服务器。

我想画一张温度和湿度如何变化的图表,即一夜之间。我的想法是根据过去 24 小时的数据绘制图表。

我自己搞不清楚,所以我想也许我可以在这里寻求帮助。当然,每个测量文档都有一个名为 createdAt 的字段,其中包含创建它的时刻的时间戳。

我需要构建一个 mongoose 查询,该查询将检索过去 24 小时内收集的测量值,但每小时只进行一次测量。使用设备测量的 5 分钟时间间隔,我将每小时创建 12 个文档。我想每小时只检索其中一个。

到目前为止,我能够想出这个(使用gt 获取最近 24 小时的测量值,不知道如何每小时只获取一个文档):

Measurements.find({ "createdAt": { $gt: new Date(Date.now() - 24*60*60 * 1000) } })

【问题讨论】:

  • 每小时需要哪些文件的标准是什么?我认为这没有灵丹妙药。您只需过滤查询结果即可获得所需的测量值。

标签: node.js mongodb mongoose


【解决方案1】:

使用聚合

this is a great article 了解如何对文档进行分组,然后为每个文档选择一项。

您还需要过滤过去 24 小时的文档,然后从时间戳中投射 find 和 hour

如果你需要,比如说过去 48 小时,你需要按小时和天分组。

您的查询将是这样的

collection.aggregate([
  {
    "$filter": {
      "createdAt": { $gt: new Date(Date.now() - 24*60*60 * 1000) }
    }
  },
  {
    "$project": {
      "h": {"$hour" : "$createdAt"},
      "original_doc": "$$ROOT"
    }
  },
  {
    "$group": {
      "_id": { "hour": "$h" },
      "docs": { $push: "$original_doc" } 
    }
  },
  { 
    $replaceRoot: {
      newRoot: { $arrayElemAt: ["$docs", 0] }
    }
  }
])

【讨论】:

    【解决方案2】:

    您可以使用以下聚合来获取每小时的第一个和最后一个文档。

    $sort 按 createdAt 排序文档,后跟 $group 每小时输出第一个和最后一个文档。

    $$ROOT 是访问整个文档的系统变量。

    Measurements.aggregate([
      {"$match" : {"createdAt":{"$gt":new Date(Date.now() - 24*60*60 * 1000)}}},
      {"$sort":{"createdAt":-1}},
      {"$group":{
        "_id":{"$hour":"$createdAt"},
        "first":{"$first":"$$ROOT"},
        "last":{"$last":"$$ROOT"}
      }}
    ])
    

    【讨论】:

      【解决方案3】:

      对我有用:

      var pipeline = [
                  {
                      $match: {
                          $and: [
                              {createdAt: {$gte: startDate}},
                              {createdAt: {$lte: endDate}},
                              {eventType: 'update'}
                          ]
                      }
                  },
                  {$sort: {createdAt: -1}},
                  {
                      $group: {
                          _id: "$person",
                          persons: {$push: "$$ROOT"}
                      }
                  },
                  {
                      $replaceRoot: {
                          newRoot: {$arrayElemAt: ["$persons", 0]}
                      }
                  },
                  {
                      $lookup: {
                          from: 'people',
                          localField: 'person',
                          foreignField: '_id',
                          as: 'person'
                      }
                  },
                  {$unwind: "$person"}
              ];
      
              VisitEvent.aggregate(pipeline)
                  .then(function (events) {ere
      

      【讨论】:

        猜你喜欢
        • 2012-10-30
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多