首页 > 解决方案 > 使用 Neo4j 进行接触者追踪 - 有些人未被识别

问题描述

我正在使用 Neo4j 开发一个联系人跟踪框架。有两种类型的节点,即PersonLocation。Person 和 Location 之间存在 VISITED 关系该关系具有startTSendTS属性。例子:

在此处输入图像描述

如果第 1 个人被感染,我需要使用图形数据库检索与他有直接或间接联系的所有其他个人节点。我遍历导致人员节点的所有关系,并应用一个公式来确定当前人员(人员 2)是否与前一个人员(人员 1)同时出现在特定位置。对标识的所有人员节点重复此过程。在上图中,人 2 根据他们的 startTS 和 endTS 与人 1 联系。这是我的代码:

MATCH path =(infected:Person {id:'1'})-[*]-(otherPerson:Person)
WITH RELATIONSHIPS(path) as rels,otherPerson
WHERE all(i in range(1,size(rels)-1)  WHERE (rels[i].endTS >= rels[i-1].startTS AND rels[i].startTS<= rels[i-1].endTS))
RETURN otherPerson

在下面的场景中,第 1 个人感染了第 2 个人,第 2 个人感染了第 3 个人。但是,即使第 3 个人明显与第 2 个人接触,代码也没有将第 3 个人识别为感染者。任何帮助将不胜感激。谢谢。

在此处输入图像描述

标签: neo4jcyphergraph-databases

解决方案


您迭代关系并将每个关系的时间戳与其前身进行比较。但是,您只想比较VISITED两个人之间的关系(Person)-[:VISITED]-(Location)-[:VISITED]-(Person)。但是在您的方法中,您也在比较两个位置之间的关系(Location)-[:VISITED]-(Person)-[:VISITED]-(Location)。一个人不可能同时在两个地点。

因此,您只想每隔两对关系进行比较。由于您使用的是索引,因此您可以轻松地使用模运算符,以便两个位置(或与一个人)之间的关系对始终为真:

MATCH path = (infected:Person {id:'1'})-[*]-(otherPerson:Person)
WITH relationships(path) as rels, otherPerson
WHERE all(i in range(1, size(rels)-1)
  WHERE i % 2 = 0
  OR (rels[i].endTS >= rels[i-1].startTS AND rels[i].startTS <= rels[i-1].endTS)
)
RETURN otherPerson

推荐阅读