为什么不在每个分离度上获得预期的节点数?

时间:2016-10-15 22:08:49

标签: neo4j cypher

我有像这样设置的数据

(Employee)-[:MANAGES]->(Employee)

它是严格等级的,即每个员工只有一个经理,顶部有一个老板。

当我这样做时

MATCH (e:Employee) RETURN count(e)

我得到 4197 。然后,当我做

MATCH 
  p=(e:Employee)<-[m:MANAGES*]-(:Employee {id: 'x'})
WITH 
  count(e) as people,
  length(p) as distance
RETURN people, distance
ORDER BY distance DESC

x 是最高老板,我得到一个如下所示的列表:

╔═══════════╦═════════╗
║ DISTANCE  ║ PEOPLE  ║
╠═══════════╬═════════╣
║  1        ║    24   ║
║  2        ║   152   ║
║  3        ║   698   ║
║  4        ║  2019   ║
║  5        ║  3275   ║
║  6        ║  1942   ║
║  7        ║   117   ║
╚═══════════╩═════════╝

(顺便说一下,当我将星号为MANAGES改为 * 5 时,距离5的结果相同)

总和显然超过了总数,因此不知何故的东西被计算为双倍 - 这就是问题所在。我显然正在遭遇关于正在发生的事情的误解

2 个答案:

答案 0 :(得分:2)

[为清晰起见而编辑。 - ed。]您需要将DISTINCT关键字添加到COUNT聚合语句中。

MATCH p = (e:Employee)<-[:MANAGES*]-(:Employee {id: 'x'})
WITH LENGTH(p) as distance, COUNT(DISTINCT e) as people,
RETURN people, distance
ORDER BY distance DESC

由于您选择的端点(员工)有多条路径,因此您在自动重复数据删除过程中会遇到一些深层次的伏都教。匹配路径模式将找到员工的路径,然后分配节点&amp;基于该路径的关系别名。除了匹配财产或在您的架构中确保您没有替代路线,(更好)之外,无法找到一组单个节点(员工)使用路径查找和DISTINCT的组合。下面的这个例子使它更清晰一点,虽然它更慢并且可能破坏信息:

MATCH (boss:Employee {id:'x'})
WITH boss
MATCH (e:Employee)<-[:MANAGES*]-(boss)
WITH DISTINCT e, boss
MATCH path = shortestPath( (e) <- [:MANAGES*] - (boss) )
RETURN length(path) AS distance, COUNT(e)

所以这只是找到所有落在老板下面的员工,确保(DISTINCT)每个员工只能在一行中继续(没有重复),然后为每个员工找到< em>只是到老板的最短路径。现在,每个员工都有一个保证的单一路径,因此当您汇总和计算时,每人只能获得1个计数。

现在,如果你有&#34;横向&#34;之前的层次关系(员工有多条不同长度的 导致它们),此方法和上述方法将产生不同的数字。第一个示例中的DISTINCT确保仅计算与老板特定距离的不同员工,因此同一员工可能出现在多行中。第二个例子虽然速度较慢,但​​首先将DISTINCT应用于整个潜在员工组,然后仅将其计入管理的最短路径,这确实会丢失一些数据,但会确保总数一致。您可以考虑哪一个适合您的使用。

答案 1 :(得分:0)

令人费解。我猜测可能存在您不知道的数据问题。我假设id是唯一受约束的,因此作为完整性检查,请尝试此查询以查看是否有人被计算两次:

MATCH 
  (e:Employee)<-[m:MANAGES*]-(:Employee {id: 'x'})
WITH e, count(e) as occurrences
RETURN e, occurrences 
WHERE occurrences > 1
ORDER BY occurrences DESC

如果有一些被计算两次,您可能需要检查由多个人管理的员工,这会导致他们在您的查询中被多次计算:

MATCH (e:Employee)
WITH e, SIZE( (e)<-[:MANAGES]-(:Employee) ) as managers
RETURN e, managers 
WHERE managers > 1
ORDER BY managers DESC