注意:我正在使用图形数据库(具体来说是 OrientDB)。这让我可以自由地用 javascript 或 groovy 编写服务器端函数,而不是仅限于使用 SQL 来解决这个问题。*
注 2:由于这是一个图形数据库,因此下面的箭头只是描述数据流。我实际上并不需要在查询中返回箭头。箭头代表关系。*
我有以时间流方式表示的数据;即,EventC 在 EventB 之后发生,EventB 在 EventA 之后发生,等等。该数据来自多个源,因此它不是完全线性的。它需要聚集在一起,这就是我遇到的问题。
目前数据看起来像这样:
# | event | next
--------------------------
12:0 | EventA | 12:1
12:1 | EventB | 12:2
12:2 | EventC |
12:3 | EventA | 12:4
12:4 | EventD |
其中“下一个”是时间流中下一个事件的 out() 边缘。在图表上,结果看起来像:
EventA-->EventB-->EventC
EventA-->EventD
由于这些数据需要聚合在一起,我需要合并重复的事件但保留它们的边缘。换句话说,我需要一个选择查询,该查询将导致:
-->EventB-->EventC
EventA--|
-->EventD
在此示例中,由于 Event 和 Event 均在 Event 之后发生(只是在不同时间),因此选择查询将显示 EventA 的两个分支,而不是两个单独的时间流。
EDIT #2
如果要将一组附加数据添加到上面的数据中,使用 EventB->EventE,生成的数据/图表将如下所示:
# | event | next
--------------------------
12:0 | EventA | 12:1
12:1 | EventB | 12:2
12:2 | EventC |
12:3 | EventA | 12:4
12:4 | EventD |
12:5 | EventB | 12:6
12:6 | EventE |
EventA-->EventB-->EventC
EventA-->EventD
EventB-->EventE
我需要一个查询来生成一棵树,例如:
-->EventC
-->EventB--|
| -->EventE
EventA--|
-->EventD
编辑 #3 和 #4
这里显示的数据带有边缘,与上面的“下一”列相反。我还在此处添加了几个附加列,希望能够消除有关数据的任何混淆:
# | event | ip_address | timestamp | in | out |
----------------------------------------------------------------------------
12:0 | EventA | 123.156.189.18 | 2015-04-17 12:48:01 | | 13:0 |
12:1 | EventB | 123.156.189.18 | 2015-04-17 12:48:32 | 13:0 | 13:1 |
12:2 | EventC | 123.156.189.18 | 2015-04-17 12:48:49 | 13:1 | |
12:3 | EventA | 103.145.187.22 | 2015-04-17 14:03:08 | | 13:2 |
12:4 | EventD | 103.145.187.22 | 2015-04-17 14:05:23 | 13:2 | |
12:5 | EventB | 96.109.199.184 | 2015-04-17 21:53:00 | | 13:3 |
12:6 | EventE | 96.109.199.184 | 2015-04-17 21:53:07 | 13:3 | |
像这样保存数据以保留每个单独的事件和会话流(由 IP 地址标记)。
TL;DR
有很多事件,其中一些是重复的,需要将它们全部组织成一个整洁的时间流程图。