我需要一个 MongoDB 查询来检索每天的文档计数,以便为我的业余无线电接收信号历史可视化服务 SpotViz 提供热图显示(使用 https://kamisama.github.io/cal-heatmap/ )。
提供给 Cal-heatmap 的数据如下所示:
{
"946721039":4,
"946706853":2,
"946706340":7,
...
}
这个数据结构的有趣之处在于属性名称是可变的,我不确定如何将结果投影到 MongoDB 查询中的属性名称中。我在 StackOverflow 上问了这个问题: “Return a computed value as field name in MongoDB query?” – 到目前为止我还没有得到任何答案或建议,所以我不确定这是否可行。
似乎没有办法完全满足我的需要,所以我的下一个挑战是如何每天对文档进行分组(忽略日期的时间部分),并返回每天的计数。
我从 shell 中的工作聚合查询开始,然后使用 MongoDB Java api 实现它。此查询的挑战在于,似乎没有任何开箱即用的功能允许您根据日期选择匹配文档并排除 new Date() 的时间部分。我需要的是等同于“查找按同一天分组的文档数”。要注意的是不要按完全相同的 yyyy/MM/dd hh:mm:ss 值对文档进行分组,而是仅按相同的 yyyy/MM/dd 值进行分组。
由于有一种方法可以使用聚合 $year、$month、$dayOfMonth 运算符从日期中提取年、月和日值,这些可用于获取我需要的结果(每天的计数),但这种格式不能帮助我获取 1970 年 1 月 1 日之后几秒内计数的属性名称,例如“946721039”。
使用这种方法的查询如下所示:
{
"946721039":4,
"946706853":2,
"946706340":7,
...
}
…此方法遵循 此 SO 帖子 的建议。
这种按天对文档计数进行分组的方法很好,但它不会返回自 1/1/1970 以来每天以秒表示的格式的文档。
更好的方法是按日期分组,然后返回该值。然而,将 mongo 中的日期转换为另一种格式似乎有些挑战——我可能花了太多时间来计算一个查询来执行此操作,接近了,但仍然不是我想要的,并以这个相当复杂的查询结束:
{
"946721039":4,
"946706853":2,
"946706340":7,
...
}
我试图用这种方法做的是使用 $project 阶段从每个时间戳值中减去转换为毫秒的 $hour、$minute 和 $second 值,以获得 yyyy/MM/dd 的毫秒值但忽略时间部分。这与我得到的差不多,但我无法让数学工作,或者至少无法在类型之间进行转换,因此计算将按照我想要的方式进行。
我的下一次尝试是基于 这篇 SO 帖子 中的建议。这是解决问题的一种更简单的方法——我的新查询如下所示:
{
"946721039":4,
"946706853":2,
"946706340":7,
...
}
如果我尝试将其分解为文字,那么我正在做的是:
– 对于日期 x,计算自 1/1/1970(纪元日期)以来的毫秒数
– 从中减去自一天开始以来的毫秒数(这是自 1/1/1970 以来的毫秒数 mod 一天中的毫秒数,余数除以另一个)
...结果是每个日期在午夜的毫秒数,即不包括时间部分。
好的,差不多了!我如何处理这个查询并将其转换为 MongoDB Java Drvier API 将在第 2 部分中介绍。
如果您喜欢这篇文章并想了解有关 MongoDB 的更多信息,请查看有关 MongoDB 的所有 教程和文章的集合 。