【问题标题】:MongoDB aggregate by time windowMongoDB 按时间窗口聚合
【发布时间】:2026-01-21 00:05:02
【问题描述】:

我正在努力为我的 MongoDB 数据库创建聚合查询。

数据库非常大(+10GB),因此即使在很短的时间窗口(数万个文档)内手动聚合也很慢。

文档样本始终遵循以下结构:

{
  "_id":ObjectId("568285c5693a7336bb16c817"),
  "DetectTime":"2015-12-29T13:08:21Z",
  "Node":[
    {
      "Type":["Flow","Statistical"],
      "SW":["Nemea","HostStatsNemea"],
      "Name":"cz.cesnet.nemea.hoststats"
    }
  ],
  "EventTime":"2015-12-29T13:07:05Z",
  "Description":"Horizontal port scan",
  "ConnCount":254,
  "CeaseTime":"2015-12-29T13:07:46Z",
  "Format":"IDEA0",
  "Category":["Recon.Scanning"],
  "ID":"924c76d4-7c4d-45d8-b1b1-3dc36cf47729",
  "Source":[
    {
      "IP4":["192.168.0.254"],
      "Proto":["tcp"]
    }
  ],
  "FlowCount":254,
  "CreateTime":"2015-12-29T13:08:21Z"
}

对我来说重要的是我想要聚合的CategoryDetectTime。使用DetectTime,我想为每个Category 实现聚合N 分钟,并对每个聚合求和FlowCount。我真的很挣扎,因为DetectTime 不是日期而是字符串,因此我无法正常使用它。

我真的被困住了,非常感谢任何帮助!

【问题讨论】:

  • 将日期字段更改为真正的 BSON Date 对象。真的。此外,找到负责将这些存储为字符串的代码并修复它。 1. 您将能够以简单且高效的方式做您想做的事。 2. 当前字符串表示浪费了大量存储空间,因为 BSON 日期在内部存储为整数(自纪元以来的毫秒数),并且将使用更少的空间。这是您需要向老板提出的两种情况。如果您不这样做,那么这只是解决问题的另一个问题。
  • @BlakesSeven 我没有意识到存储表示和节省空间的区别。这就是说服我的同事改变它的原因。现在整个数据库都被更改了,我在不到一个小时的时间内创建了所需的查询。再次感谢!

标签: python mongodb mongodb-query pymongo


【解决方案1】:

您的问题是 DetectTimestring 而不是 datetime 对象。我很确定您必须在您的逻辑中对datetimesomewhere 进行比较。要进行比较,您需要通过这样做将string 转换为datetime 对象

from datetime import datetime as dt
detectTime = dt.strptime("2015-12-29T13:08:21Z", "%Y-%m-%dT%H:%M:%SZ")

您可以对所有条目执行一次并将其存储在 MongoDB 中。

【讨论】:

  • 感谢您的快速响应,但很遗憾我无法更改文档的架构(这是我们公司标准给出的)。我的 python 代码中已经有了这种逻辑,我想在 MongoDB 本身中实现它。
  • @PetrStehlik 如果您可以更改数据结构,那么最好的选择是 mapReduce。