如何有效地计算组织图中两个团队之间发送的消息



我们有一个电子邮件通信图,它有以下节点。人员{姓名、职务、角色}消息{sent_time,property1,property2,..}

关系如下

节点:人员-->rel:REPORTS_TO-->节点:人员

节点:人员-->rel:SEND_EMAIL-->节点:消息--->rel:RECEIVES_EMAIL-->节点:人员

正如你可以想象的那样,在团队沟通中,员工和经理之间存在1:1的关系。多个员工可以向同一经理报告。一个员工可以向多个员工发送一条消息,因此员工和消息之间存在1:1的SENDS_EMAIL关系,而消息和其他员工之间存在1:n RECEIVES_EMAIL关系。

给出这张图,我想在图中找不到任何两名经理A和B之间交换的消息,也就是说,没有经理"A"管理链中的任何人(不仅仅是直接下属)向经理"B"管理链上的任何人发送的电子邮件。

该图有10万个员工节点和1500万条消息,总共有1.8亿个关系。我们使用的是最新的neo4j 2.2社区版,其中包含节点和关系的所有属性的模式索引。

我写了下面的密码查询来获得这些信息。但这是非常缓慢的,即在64GB RAM的windows服务器上返回结果>1分钟。

MATCH (:Person { name:'A' }) <-[:ReportTo*]-(AO:Person) WITH AO
MATCH (:Person { name:'B' }) <-[:ReportTo*]-(BO:Person) WITH BO,AO
MATCH (AO)-[m:SENDS_EMAIL]-->(BO) RETURN COUNT(m)

有没有更有效的方法来编写这个密码查询?如果不是,我们如何对图进行建模以快速服务于该查询,即<1-2秒。

谢谢你的帮助

使用Neo4j 2.2。

您可能希望从0..开始,以便包括经理本人。

它必须计算两个集合之间的叉积,

您可能希望将其限制为不同的用户。

MATCH (:Person { name:'A' }) <-[:REPORTS_TO*0..]-(AO:Person) 
// reduce cardinality to 1, to execute the following matches not n times
WITH collect(distinct AO) as first
MATCH (:Person { name:'B' }) <-[:REPORTS_TO*0..]-(BO:Person) 
WITH distinct BO,first
UNWIND first as AO
RETURN SUM(SIZE((AO)-[:SENDS_EMAIL]->(BO)))

最新更新