1

想象一下:

{
    "user" : "john",
    "type" : "connect",
    "created" : ISODate("2015-10-02T10:00:00.000Z"),
    "__v" : 0
},
{
    "user" : "john",
    "type" : "disconnect",
    "created" : ISODate("2015-10-02T10:10:00.000Z"),
    "__v" : 0
},
{
    "user" : "frank",
    "type" : "connect",
    "created" : ISODate("2015-10-02T10:05:00.000Z"),
    "__v" : 0
},
{
    "user" : "frank",
    "type" : "disconnect",
    "created" : ISODate("2015-10-02T10:15:00.000Z"),
    "__v" : 0
},
{
    "user" : "john",
    "type" : "connect",
    "created" : ISODate("2015-10-02T10:15:00.000Z"),
    "__v" : 0
}

我想创建一个中断报告,告诉“用户 john 有 5 分钟的停机时间”。我现在完全处于黑暗之中,我深入研究了聚合以及 mapReduce,但似乎没有任何东西指向我需要它的方向。我可以使用普通的 javascript 来解决它,但我想避免这种情况,因为 MongoDB 是为这些类型的聚合而设计的。也许我只是陷入困境,需要让它休息一段时间,但也许有人对我有一个很好的解决方案。

所以最好的输出是(我猜):

{
    "user" : "john",
    "outage": "5"
}

除了这个“最佳”示例之外,在部署新服务器版本时,系统可能会吞下断开连接。这些大约是 10 秒,为了方便起见,我正在考虑将它们排除在外。

4

1 回答 1

1

询问

db.collection.aggregate([{$group:{_id:{user:"$user",type:"$type"},created:{$max:"$created"}}},{$sort:{"_id.user":1,"_id.type":-1}},{$group:{_id:"$_id.user","latest_disconnected":{"$first":"$created"},"latest_connected":{$last:"$created"}}},{$project:{outage:{$divide:[{"$subtract": [ "$latest_connected", "$latest_disconnected" ] },60000]}}}])

输出

{“_id”:“约翰”,“中断”:5}

{“_id”:“坦率”,“中断”:-10 }

以下是详细说明

这将为您提供每个用户的最新条目,用于连接和断开连接

{$group:{_id:{user:"$user",type:"$type"},created:{$max:"$created"}}}

不要忘记按用户和类型排序,组不保证排序输出

{$sort:{"_id.user":1,"_id.type":-1}}

由于每个用户将有 2 个来自上一个管道的条目,因此第一个条目将用于最新断开连接,最后一个(第二个)条目用于最新连接

{$group:{_id:"$_id.user","latest_disconnected":{"$first":"$created"},"latest_connected":{$last:"$created"}}}

这是简单的数学,2个日期之间的差异并转换为分钟

{$project:{outage:{$divide:[{"$subtract": [ "$latest_connected", "$latest_disconnected" ] },60000]}}}

希望它会有所帮助

于 2015-10-02T20:44:43.533 回答