Neo4j:排除可变路径关系中的某些节点
Neo4j: Exclude certain nodes in variable path relationship
我有一个图形数据库,包含两种类型的节点 - 个人和企业,以及一种类型的关系 - 付款。
一个人可以向另一个人或另一家企业付款。同样,企业可以向个人或企业付款。即这四种路径都是可能的
(person)-[:PAYS]->(person)
(person)-[:PAYS]->(business)
(business)-[:PAYS]->(person)
(business)-[:PAYS]->(business)
在检测可能的洗钱的用例中,我想提取一个人的付款在到达另一个人之前经过几家企业的情况。即(为了方便省略关系):
(person)-(business)-(business)-(business)-(person)
因此,我的密码查询应该如下所示:
(person)-[:PAYS*0..3]-(person)
但是,这也会 return 我得到以下关系,这不是我想要的:
(person)-(business)-(person)-(business)-(person)
我该怎么做才能将(人)排除在可变长度关系 [:PAYS*0..3] 之外?
我已经按照 here 给出的解决方案进行了尝试:
MATCH path((person)-[:PAYS*0..3]-(person))
WHERE NONE(n IN nodes(path) WHERE n:person)
RETURN path
但是,此查询 运行 很长时间才给出零结果输出(这是不正确的)。另一个明显的解决方案是更改我的关系以区分 [:PAYS_BUSINESS] 和 [:PAYS_PERSON],但我会在不更改图形模式的情况下找出是否有可能的解决方案。
在我发布这个问题 5 分钟后,我想到并尝试了一个似乎可行的可能解决方案。不确定这是否违反规则,但这是解决我自己问题的可能方法(以防其他人面临同样的问题):
MATCH x=(p1:person)-[:PAYS]-(b1:business)
WITH *
MATCH y=(b1:business)-[:PAYS*..3]-(b2:business)-[:PAYS]-(p2:person)
RETURN x, y
的原因
MATCH path=((person)-[:PAYS*0..3]-(person))
WHERE NONE(n IN nodes(path) WHERE n:person)
RETURN path
没有任何结果似乎是第一个和最后一个节点是人
如果你想找到从 :person 到 :person 之间只有 :business 的路径,你可以这样做
MATCH path=((p1:Person)-[:PAYS*1..3]-(p2:Person))
WHERE ALL(n IN nodes(path)[1..-1] WHERE n:Business)
RETURN path
你们可能都想看看 apoc.path.expand
和 apoc.path.expandConfig
程序 (https://neo4j.com/labs/apoc/4.1/overview/apoc.path/)。很强大,但是你引入了对APOC库的依赖。
您可能想看看我是如何通过 X-linked 继承来处理这个问题的。在该用例中,您聚合了 parent(M 或 F)的性别,然后可以从聚合字符串中排除 MM,因为男人永远不会将 X 传递给他的儿子。
http://stumpf.org/genealogy-blog/graph-databases-in-genealogy
查询排除所有 MM 连接字符串,而是接受除 MM 之外的任何内容:
match p=(n:Person{RN:32})<-[:father|mother*..99]-(m) with m, reduce(status ='', q IN nodes(p)| status + q.sex) AS c, reduce(srt2 ='|', q IN nodes(p)| srt2 + q.RN + '|') AS PathOrder where c=replace(c,'MM','') return distinct m.fullname as Fullname
在你的情况下是 P 和 B(个人或企业)。
我有一个图形数据库,包含两种类型的节点 - 个人和企业,以及一种类型的关系 - 付款。
一个人可以向另一个人或另一家企业付款。同样,企业可以向个人或企业付款。即这四种路径都是可能的
(person)-[:PAYS]->(person)
(person)-[:PAYS]->(business)
(business)-[:PAYS]->(person)
(business)-[:PAYS]->(business)
在检测可能的洗钱的用例中,我想提取一个人的付款在到达另一个人之前经过几家企业的情况。即(为了方便省略关系):
(person)-(business)-(business)-(business)-(person)
因此,我的密码查询应该如下所示:
(person)-[:PAYS*0..3]-(person)
但是,这也会 return 我得到以下关系,这不是我想要的:
(person)-(business)-(person)-(business)-(person)
我该怎么做才能将(人)排除在可变长度关系 [:PAYS*0..3] 之外?
我已经按照 here 给出的解决方案进行了尝试:
MATCH path((person)-[:PAYS*0..3]-(person))
WHERE NONE(n IN nodes(path) WHERE n:person)
RETURN path
但是,此查询 运行 很长时间才给出零结果输出(这是不正确的)。另一个明显的解决方案是更改我的关系以区分 [:PAYS_BUSINESS] 和 [:PAYS_PERSON],但我会在不更改图形模式的情况下找出是否有可能的解决方案。
在我发布这个问题 5 分钟后,我想到并尝试了一个似乎可行的可能解决方案。不确定这是否违反规则,但这是解决我自己问题的可能方法(以防其他人面临同样的问题):
MATCH x=(p1:person)-[:PAYS]-(b1:business)
WITH *
MATCH y=(b1:business)-[:PAYS*..3]-(b2:business)-[:PAYS]-(p2:person)
RETURN x, y
MATCH path=((person)-[:PAYS*0..3]-(person))
WHERE NONE(n IN nodes(path) WHERE n:person)
RETURN path
没有任何结果似乎是第一个和最后一个节点是人
如果你想找到从 :person 到 :person 之间只有 :business 的路径,你可以这样做
MATCH path=((p1:Person)-[:PAYS*1..3]-(p2:Person))
WHERE ALL(n IN nodes(path)[1..-1] WHERE n:Business)
RETURN path
你们可能都想看看 apoc.path.expand
和 apoc.path.expandConfig
程序 (https://neo4j.com/labs/apoc/4.1/overview/apoc.path/)。很强大,但是你引入了对APOC库的依赖。
您可能想看看我是如何通过 X-linked 继承来处理这个问题的。在该用例中,您聚合了 parent(M 或 F)的性别,然后可以从聚合字符串中排除 MM,因为男人永远不会将 X 传递给他的儿子。
http://stumpf.org/genealogy-blog/graph-databases-in-genealogy
查询排除所有 MM 连接字符串,而是接受除 MM 之外的任何内容:
match p=(n:Person{RN:32})<-[:father|mother*..99]-(m) with m, reduce(status ='', q IN nodes(p)| status + q.sex) AS c, reduce(srt2 ='|', q IN nodes(p)| srt2 + q.RN + '|') AS PathOrder where c=replace(c,'MM','') return distinct m.fullname as Fullname
在你的情况下是 P 和 B(个人或企业)。