所有
我是图形数据库领域的新手,想知道这种类型的示例是否适用于图形数据库。
说我在看棒球比赛。当每个玩家去击球时,有3种可能的结果:击球,三振或步行。
对于每个击球手和整个棒球赛季,我想弄清楚的是序列的数量。
例如,对于那些去过盘子n次的击球手,有多少人有特定的序列(例如,击中/步行/三振出或击中/击中/击中/击中),如果有,有多少人有相同的序列击球手重复按时间索引的相同序列。为了进一步解释,时间将允许我知道在赛季开始时,中期或后半段是否发生特定序列(例如,命中/步行/三振出或命中/命中/命中/命中)。
对于键值类型数据库,原始数据如下所示:
Batter Time Game Event Bat
------- ----- ---- --------- ---
Charles April 1 Hit 1
Charles April 1 strikeout 2
Charles April 1 Walk 3
Doug April 1 Walk 1
Doug April 1 Hit 2
Doug April 1 strikeout 3
Charles April 2 strikeout 1
Charles April 2 strikeout 2
Doug May 5 Hit 1
Doug May 5 Hit 2
Doug May 5 Hit 3
Doug May 5 Hit 4
因此,我的输出显示如下:
Sequence Freq Unique Batters Time
----------------------- ---- -------------- ------
hit 5000 600 April
walk/strikeout 3000 350 April
strikeout/strikeout/hit 2000 175 April
hit/hit/hit/hit/hit 1000 80 April
hit 6000 800 May
walk/strikeout 3500 425 May
strikeout/strikeout/hit 2750 225 May
hit/hit/hit/hit/hit 1250 120 May
. . . .
. . . .
. . . .
. . . .
如果这对于图形数据库是可行的,它还会扩展吗?如果不是击球手的3个可能的结果,那么10,000,000击球手就有10,000个可能的结果呢?
更重要的是,10,000个独特的结果将在组合设置中排序(例如10,000 CHOOSE 2,10000 CHOOSE 3等)。
我的问题是,如果图形数据库合适,您会如何建议设置解决方案?
提前非常感谢。
答案 0 :(得分:0)
自从提出这个问题以来,图形数据库已经取得了长足的进步,但问题的答案是,绝对是的,图形数据库可用于查找电池性能模式。
免责声明:我是 Objectivity, Inc. 的现场运营总监。
这不是产品插件。这个问题可以在市场上的许多产品中解决。您特别提到将问题放大,这很可能是某些产品的限制因素。
为了解决这个问题,我使用了 Objectivity/DB 数据库,该数据库是一个可大规模扩展的对象/图形数据库,具有称为声明性客观性的 DO 的全功能图形导航查询语言。
这是我用来解决问题的架构:
CREATE CLASS Season {
year : Integer,
games : List { Element: Reference { referenced: Game }, CollectionTypeName: TreeListOfReferences }
}
CREATE CLASS Game {
date : DateTime,
homeTeam : Reference { referenced: Team, inverse: homeGames },
awayTeam : Reference { referenced: Team, inverse: awayGames },
from : Reference { referenced: Season, inverse: games },
innings : Reference { referenced: Inning, inverse: game }
}
CREATE CLASS Inning {
number : Integer,
game : Reference { referenced: Game, inverse: innings },
batters : Reference { referenced: AtBat, inverse: inning }
}
CREATE CLASS AtBat {
result : String,
inning : Reference { referenced: Inning, inverse: batters },
batter : Reference { referenced: Player, inverse: atBats },
nextAtBat : Reference { referenced: AtBat, inverse: prevAtBat },
prevAtBat : Reference { referenced: AtBat, inverse: nextAtBat },
nextBatter : Reference { referenced: AtBat, inverse: prevBatter },
prevBatter : Reference { referenced: AtBat, inverse: nextBatter }
}
CREATE CLASS Player {
name : String,
teams : List { Element: Reference { EdgeClass: PlayedFor, EdgeAttribute: team }, CollectionTypeName: TreeListOfReferences },
atBats : List { Element: Reference { referenced: AtBat, inverse: batter }, CollectionTypeName: TreeListOfReferences }
}
CREATE CLASS PlayedFor {
player : Reference { referenced: Player, inverse: teams },
team : Reference { referenced: Team, inverse: players },
start : DateTime,
end : DateTime
}
CREATE CLASS Team {
name : String,
homeGames : Reference { referenced: Game, inverse: homeTeam },
awayGames : Reference { referenced: Game, inverse: awayTeam },
players : List { Element: Reference { EdgeClass: PlayedFor, EdgeAttribute: team }, CollectionTypeName: TreeListOfReferences }
}
这里是架构的摘要。每个玩家都连接到他们自己的每一个 AtBat 对象。每个玩家的 AtBat 对象作为一个双向链表存在。每个 AtBat 对象都指向拥有它的 Player。
这个想法是找到用户定义的 AtBat 对象序列,然后找到拥有该序列的 Player。在下面的查询中,我们正在寻找“Strike Out”、“Hit”和“Strike Out”模式。当我们找到该模式时,我们需要知道与该模式相关联的 Player。因为所有 AtBat 对象都链接回拥有的 Player,所以我们在查询中要做的就是表达我们想要的 AtBat 对象序列,然后从最后一个 AtBat 对象导航到它所连接的 Player 对象。查询如下:
match path = (a1:AtBat {result == "Strike Out"})
-[:nextAtBat]->(a2:AtBat {result == "Hit"})
-[:nextAtBat]->(a3:AtBat {result == "Strike Out"})
-->(p:Player)
group by p.name
return a1.result, a2.result, a3.result, p.name;
结果示例如下所示:
{
_Projection
{
a1.result:'Strike Out',
a2.result:'Hit',
a3.result:'Strike Out',
p.name:'Player0_TeamA'
},
_Projection
{
a1.result:'Strike Out',
a2.result:'Hit',
a3.result:'Strike Out',
p.name:'Player0_TeamB'
},
_Projection
{
a1.result:'Strike Out',
a2.result:'Hit',
a3.result:'Strike Out',
p.name:'Player10_TeamA'
},
此图描述了如何找到模式,然后从最后一个 AtBat 导航到关联的玩家: