图数据库节点和边随时间变化

问题描述

我想将德甲联赛映射为图形数据库中的结构。对于当前的“静态”状态,这完全没有问题:

  • 球员与俱乐部相关联。
  • 俱乐部通过比赛相互联系。
  • 俱乐部被分配到联赛中。

但是,我想引入时间维度:

  • 例如,第 3 联赛自 2008 年才成立。在此之前,联赛的结构完全不同。
  • 球员更换俱乐部

如何将其映射到图形数据库中? 不幸的是,我在像 OrientDB 这样的多模型数据库中没有找到任何东西。

解决方法

他的典型方法是在顶点和边上使用 validFrom/validTo 属性。然后你可以在查询图表时过滤这些属性。

例如

CREATE VERTEX Club SET name = 'AS Roma';
CREATE VERTEX Player name = 'Francesco',surname = 'Totti';
CREATE EDGE PlaysWith
  FROM (SELECT FROM Player WHERE surname = 'Totti)
  TO (SELECT FROM Club WHERE name = 'AS Roma')
  SET
  validFrom = date('1992-01-01','yyyy-MM-dd')
  validTo = date('2017-12-032','yyyy-MM-dd');

MATCH {class:Player,as:p}
      .outE("PlaysWith"){where:(
          validFrom < date('2001-01-01','yyyy-MM-dd')
          validTo > date('2001-01-01','yyyy-MM-dd')
      )}
      .inV(){as:Club,where:(name = "AS Roma")}
RETURN $elements;
,

在图形数据库中添加时间维度节点和边是一种非常常见的设计模式。它允许您捕获数据的所有状态,然后查看特定时间点或时间范围内的数据。

这是一个无限图解决方案:

UPDATE SCHEMA {
   CREATE CLASS Team {
      name    : String,players : LIST {
                    element: Reference {
                    edgeClass  : PlaysFor,edgeAttribute   : player
                    },CollectionTypeName : SegmentedArray
                }
  }
  CREATE CLASS Player {
     name      : String,playsFor  : LIST {
                    element: Reference {
                       edgeClass : PlaysFor,edgeAttribute  : team
                    },CollectionTypeName : SegmentedArray
                  }
  }
  CREATE CLASS PlaysFor {
      dateFrom : Date,dateTo   : Date,team     : Reference {referenced: Team,inverse: players },player   : Reference {referenced: Player,inverse: playsFor }
   }
};
//---------------------------------- Result ------------------------------------
Done.

创建一些球员和球队数据...

let teamHKiel = CREATE Team { name: "Holstein Kiel" };   
let teamMainz = CREATE Team { name: "FVZ Mainz 05 II" };
let teamSpVgg = CREATE Team { name: "SpVgg Unterhaching" };

let playerRZ = CREATE Player { name: "Robin Zentner" };
let playerAH = CREATE Player { name: "Alexander Hack" };

在特定日期范围内将球员与他们的球队联系起来。

CREATE PlaysFor { 
      player: $playerRZ,team: $teamMainz,dateFrom: 2014-08-02,dateTo: 2015-08-01 
};
//---------------------------------- Result ------------------------------------
3-3-1-14


CREATE PlaysFor { 
       player: $playerRZ,team: $teamHKiel,dateFrom: 2015-08-02,dateTo: 2016-08-01 
};
//---------------------------------- Result ------------------------------------
3-3-1-19

CREATE PlaysFor { 
       player: $playerAH,dateFrom: 2014-07-02,dateTo: 2017-06-01 
};
//---------------------------------- Result ------------------------------------
3-3-1-22

CREATE PlaysFor { 
       player: $playerAH,team: $teamSpVgg,dateFrom: 2013-07-02,dateTo: 2014-07-01 
};
//---------------------------------- Result ------------------------------------
3-3-1-25

Robin Zentner 在 2016-05-01 效力于哪支球队?

LET d = 2016-05-01;
MATCH path = (p:Player {name == 'Robin Zentner'}) 
             -[:PlaysFor {dateFrom < $d AND dateTo > $d}]->(t:Team) 
        RETURN p.name as player,t.name as team;
//---------------------------------- Result ------------------------------------
{
  _Projection
  {
    player:'Robin Zentner',team:'Holstein Kiel'
  }
}

设置一个不同的日期。

//---------------------------------- Statement ---------------------------------
// LET d = 2015-05-01;
//---------------------------------- Result ------------------------------------
Done.

Robin Zentner 在 2015-05-01 效力于哪支球队?

MATCH path = (p:Player {name == 'Robin Zentner'}) 
            -[:PlaysFor {dateFrom < $d AND dateTo > $d}]->(t:Team) 
            RETURN p.name as player,t.name as team;
//---------------------------------- Result ------------------------------------                  
{
  _Projection
  {
    player:'Robin Zentner',team:'FVZ Mainz 05 II'
  }
}

谁在 2015-03-01 为 FVZ Mainz 05 II 效力?

LET d = 2015-03-01;
//---------------------------------- Result ------------------------------------
Done.

MATCH path = (t:Team {name == 'FVZ Mainz 05 II'}) 
             -[:PlaysFor {dateFrom < $d AND dateTo > $d}]-> 
             (p:Player) 
             RETURN p.name as player,t.name as team;
//---------------------------------- Result ------------------------------------

{
  _Projection
  {
    player:'Robin Zentner',team:'FVZ Mainz 05 II'
  },_Projection
  {
    player:'Alexander Hack',team:'FVZ Mainz 05 II'
  }
}

#InfiniteGraph