如何根据每个连接节点对的节点和关系属性来限制递归

时间:2018-03-08 21:57:57

标签: neo4j cypher

让我们从简单查询开始,以递归方式找到所有同事。

match (user:User {username: 'John'})
match (user)-[:WORKED_WITH *1..]-(coworkers:User)
return user, coworkers

现在,我必须对其进行修改,以便仅接收与第一个N关系相关联的用户。

每个User标签在属性中都有N的值,并且每个关系都在其属性中包含创建日期。

我想,创建和维护满足这种条件的单独关系集是合理的。

UPD:限制必须仅适用于直接相互了解的人。

必须对路径中的每个节点应用限制,例如第一个用户有3个关系:WORKED_WITH(在第一级)和限制5,比一切正常我们可以继续检查连接的用户,如果用户有6个关系和限制5,只有5个关系必须用于移动上。

我明白它可能是慢查询,但如果没有手写工具怎么做呢?改进之一是将查询执行中的所有限制转移到一些预处理步骤中,并创建将保留所有这些限制的其他类型的关系,它将需要验证,因为它们不是状态的一部分而是状态的投影。 / em>的

1 个答案:

答案 0 :(得分:1)

以下查询应该有效(只要您没有大量数据)。它使用DISTINCT删除重复项。

MATCH (user:User {username: 'John'})-[:WORKED_WITH*]-(coworker:User)
WITH DISTINCT user, coworker
ORDER BY coworker.createDate
RETURN COLLECT(coworker)[0..user.N] AS coworkers;

注意:由于可变长度路径具有指数复杂性,因此通常需要指定合理的上限(例如[:WORKED_WITH*..5])以避免查询运行时间过长或导致内存不足错误。此外,由于LIMIT运算符不接受变量作为其参数,因此此查询使用COLLECT(coworker)[0..user.N]来获取最早N的{​​{1}}同事 - 这也是有点贵。

现在,如果(正如您的建议),您已在每个createDate及其FIRST_WORKED_WITH最早的“同事”之间创建了特定类型的关系(例如User),那将允许您可以使用以下简单快速的查询:

N