我有一个集合,其中存储了某一天的配水量。现在,在设备未运行的某些天,数据不会存储在数据库中,我也不会在集合中获取数据。例如,我查询过去7天的配水量,而设备仅运行了两天,结果如下:
[{
"uID" : "12345678",
"midNightTimeStamp" : NumberInt(1645381800),
"waterDispensed" : NumberInt(53)
},
{
"uID" : "12345678",
"midNightTimeStamp" : NumberInt(1645641000),
"waterDispensed" : NumberInt(30)
}]
转换上述两个时间戳后,我得到了2月21日星期一和2月24日星期四的数据。现在,如果我运行2月21日到2月27日的查询,如下所示:
db.getCollection("analytics").find({ uID: "12345678", midNightTimeStamp: {"$in": [1645381800, 1645468200, 1645554600, 1645641000, 1645727400, 1645813800, 1645900200]}})
这只返回以上两个文档,如何填充midNightTimeStamp的缺失值,以获得不存在的文档列表:
[{
"uID" : "12345678",
"midNightTimeStamp" : 1645381800,
"waterDispensed" : 53
},
{
"uID" : "12345678",
"midNightTimeStamp" : 1645468200,
"waterDispensed" : 0
},
{
"uID" : "12345678",
"midNightTimeStamp" : 1645554600,
"waterDispensed" : 0
},
{
"uID" : "12345678",
"midNightTimeStamp" : 1645641000,
"waterDispensed" : 30
},
{
"uID" : "12345678",
"midNightTimeStamp" : 1645727400,
"waterDispensed" : 0
},
{
"uID" : "12345678",
"midNightTimeStamp" : 1645813800,
"waterDispensed" : 0
},
{
"uID" : "12345678",
"midNightTimeStamp" : 1645900200,
"waterDispensed" : 0
}
3条答案
按热度按时间m1m5dgzv1#
也许是这样的:
解释道:
1.$分组文档以查找时间戳的最大值和最小值,$将所有元素推入名为“ar”的临时数组
1.$投影数组$Map,生成日期范围为最大值和最小值,步长为1x天(86400),用waterDispanced填充空元素:0
1.$展开数组$ar
1.$在最终输出中只投影我们需要的字段。
playground
qeeaahzv2#
这与另一个答案有一点不同,它只需要抓住所需的
"uID"
。MQL中的注解解释了这个过程。在mongoplayground.net上试试。
r1zk6ea13#
从MongoDB5.1开始,您可以使用
$densify
聚合操作符用平均值或默认值填充缺失的时间序列数据。https://www.mongodb.com/docs/rapid/reference/operator/aggregation/densify/
在您的情况下,可能需要在聚合时将时间戳字段转换为日期,以便可以使用
$densify
。您还可以在MongoDB World 2022上观看this presentation中
$densify
的快速解释。