我在mongo中有一个集合,其中的每个文档都包含一个时间戳数组,我需要查找(汇总)在给定时间范围内时间戳最多的文档。
我知道我需要使用$ aggregate,但是在弄清楚如何过滤和计算数组中元素的数量时遇到了麻烦。
示例文档如下:
{
"_id" : "en.m.wikipedia.org",
"times" : [
ISODate("2019-06-03T14:19:33.405Z"),
ISODate("2019-06-03T14:19:52.394Z"),
ISODate("2019-06-03T14:29:15.474Z"),
ISODate("2019-06-03T14:29:30.768Z"),
ISODate("2019-06-03T14:30:25.578Z"),
ISODate("2019-06-03T15:00:22.493Z"),
ISODate("2019-06-03T15:05:03.759Z"),
ISODate("2019-06-03T15:18:05.677Z"),
ISODate("2019-06-03T15:38:22.771Z"),
ISODate("2019-06-03T15:44:51.025Z"),
ISODate("2019-06-03T15:45:15.336Z"),
ISODate("2019-06-03T15:49:06.227Z"),
ISODate("2019-06-03T17:10:19.396Z"),
ISODate("2019-06-03T18:02:37.093Z"),
ISODate("2019-06-03T18:39:29.812Z"),
ISODate("2019-06-03T19:06:49.310Z"),
ISODate("2019-06-03T19:46:52.381Z"),
ISODate("2019-06-03T20:16:45.675Z"),
],
"source" : ["Admin"]
}
理想的输出将是这样,计数仅显示给定时间段内的时间戳数:
[
{_id: "en.m.wikipedia.org", count: 12},
{_id: "facebook.com", count: 7},
etc...
]
答案 0 :(得分:0)
根据我的理解
我设计了以下解决方案,
db.wikidata.aggregate([
{
$unwind: "$times"
},
{
$match: {
"times": {
$gte: ISODate("2019-06-03T14:30:25.578Z"),
$lte: ISODate("2019-06-03T19:46:52.381Z")
}
}
},
{
$group: {
"_id": "$_id",
"count": {
$sum: 1
}
}
}
])
输出:
{ "_id" : "en.m.wikipedia.org", "count" : 13 }
现在让我解释一下mongo查询,
{
$unwind: "$times"
}
这将创建一个与“ times”数组中每个值相对应的文档。 这将用于在给定的时间范围内匹配我们的文档。
{
$match: {
"times": {
$gte: ISODate("2019-06-03T14:30:25.578Z"),
$lte: ISODate("2019-06-03T19:46:52.381Z")
}
}
}
以上条件根据给定的时间窗口过滤文档。 您可以在javascript中生成ISO日期,并对其进行更新以设置自己的限制。
{
$group: {
"_id": "$_id",
"count": {
$sum: 1
}
}
}
这会根据“ id”字段对您的文档进行分组。
注意:我为集合使用了任意名称。