当前位置: 首页 > 知识库问答 >
问题:

MongoDB:通过拆分id进行聚合和分组

宦瀚
2023-03-14

我的模式实现受到了mongo官方网站上这篇教程的影响

{  
  _id: String,
  data:[
        {
         point_1: Number,
         ts: Date
        }
  ]
}

这基本上是为时间序列数据设计的模式,我将每个设备每小时的数据存储在单个文档中的数组中。我创建_id字段组合发送数据和时间的设备id。例如,如果id为xyz1234的设备在2018-09-11 12:30:00发送数据,则我的 字段将变为 xyz123 4:2018091112

如果该设备的那一小时的文档不存在,我会创建新文档,否则我会将数据推送到data数组。

client.db('iot')
.collection('iotdata')
.update({_id:id},{$push:{data:{point_1,ts:date}}},{upsert:true});

现在我在做聚合时遇到了问题。我试图得到这些类型的值

  • 过去 24 小时内许多设备的最小point_1值,按设备 ID 分组
  • 过去 24 小时内许多设备的最大point_1值,按设备 ID 分组
  • 过去 24 小时内按设备 ID 分组的多个设备的平均point_1

我认为这是非常简单的聚合,然后我意识到设备ID不是直接的,而是与时间数据混合在一起的,所以按设备ID分组数据不是那么直接。我如何根据设备ID拆分_id和组?我尽力把问题写得尽可能清楚,所以如果问题的任何部分不清楚,请在评论中提问。


共有2个答案

益明朗
2023-03-14

您可以在3.6中使用下面的查询。

db.colname.aggregate([
  {"$project":{
    "deviceandtime":{"$split":["$_id", ":"]},
    "minpoint":{"$min":"$data.point_1"},
    "maxpoint":{"$min":"$data.point_1"},
    "sumpoint":{"$sum":"$data.point_1"},
    "count":{"$size":"$data.point_1"}
  }},
  {"$match":{"$expr":{"$gte":[{"$arrayElemAt":["$deviceandtime",1]},"2018-09-10 00:00:00"]}}},
  {"$group":{
    "_id":{"$arrayElemAt":["$deviceandtime",0]},
    "minpoint":{"$min":"$minpoint"},
    "maxpoint":{"$max":"$maxpoint"},
    "sumpoint":{"$sum":"$sumpoint"},
    "countpoint":{"$sum":"$count"}
  }},
  {"$project":{
    "minpoint":1,
    "maxpoint":1,
    "avgpoint":{"$divide":["$sumpoint","$countpoint"]}
  }}
])
苍兴怀
2023-03-14
匿名用户

您可以从对数据的$unwind开始,以获得每个条目的单个文档。然后,您可以使用substr和indexOfBytes操作符获取< code>deviceId。然后,您可以应用您的过滤条件(过去< code>24小时)并使用< code>$group获取< code>min 、< code>max和< code>avg

db.col.aggregate([
    {
        $unwind: "$data"
    },
    {
        $project: {
            point_1: "$data.point_1",
            deviceId: { $substr: [ "$_id", 0, { $indexOfBytes: [ "$_id", ":" ] } ] },
            dateTime: "$data.ts"
        }
    },
    {
        $match: {
            dateTime: { $gte: ISODate("2018-09-10T12:00:00Z") }
        }
    },
    {
        $group: {
            _id: "$deviceId",
            min: { $min: "$point_1" },
            max: { $max: "$point_1" },
            avg: { $avg: "$point_1" }
        }
    }
])

 类似资料:
  • 我想分割交换消息体(它是MyCustomClass对象的列表),处理它们(一个接一个),然后将所有的交换聚合在一起。拆分可以,一个一个处理也可以,但是我想不出怎么把它们聚合起来。 我不需要复杂的聚合,只需要收集分离的交换列表,并在最终的处理器中处理它们。

  • 目前,我正在与spring integration合作开发新的应用程序,并启动了poc,以了解如何处理故障案例。在我的应用程序中,spring integration将接收来自IBM mq的消息,并根据消息类型验证头信息和到不同队列的路由。传入的消息可能是批量消息,所以我使用了spring integration的拆分器和聚合器,并且对技术工作流程有很好的进展和控制。目前我面临的问题很少,我们有I

  • 我们在Camel中定义了一个具有拆分和聚合功能的路由,但无法在聚合器之后将异常传播回拆分。这导致即使我们遇到异常,拆分也会运行 下面是不工作的代码 上述代码中的处理器(myProcessor)如下: 但是,当我从路由中移除聚合时,Split能够在异常情况下停止路由。

  • 我试图在使用RESTendpoint的骆驼路由中构建一个分割/聚合模式。它需要一个包含请求详细信息列表的请求对象。我想并行处理请求详细信息,然后将聚合结果返回给调用方。我希望这是一个同步调用。 这是我的路线中的代码。 我希望调用的结果是聚合调用(我的响应对象)的输出。但我实际上得到的是REST调用返回的请求对象?? 当我放入更多的日志语句时,我可以看到Split调用正在触发多个线程,这很好。我可以

  • 本文向大家介绍MongoDB聚合分组多个结果,包括了MongoDB聚合分组多个结果的使用技巧和注意事项,需要的朋友参考一下 要聚合多个结果,请在MongoDB中使用$group。让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出- 以下是汇总组多个结果的查询- 这将产生以下输出-

  • 我有一个复杂的组查询。 数据如下: 汇总如下: null