我是Neo4j的新手,但不是图表,我有一个特定的问题,我无法用Cypher解决。
使用此类数据:
我希望能够在单个查询中跟踪一些传入流和一些传出流。
示例:
我的问题是Cypher只允许在关系模式中指定一个方向。
所以我可以做(source)-[:A|:B*]->() or (source)<-[:A|:B*]-()
。
但我无法告诉Cypher我想要关注-[:A]-> and <-[:B]-
。
顺便说一句,我知道我可以做-[:A|:B]-
,但这不会解决我的问题,因为我不想关注-[:B]->
和<-[:A]-
。
提前感谢您的帮助:)
答案 0 :(得分:2)
除了@Gabor Szarnyas的回答,我认为您可以使用APOC程序apoc.path.expand来实现目标。
使用此样本数据集:
CREATE (:Source)-[:A]->()-[:A]->()<-[:B]-()-[:A]->()
并致电apoc.path.expand
:
match (source:Source)
call apoc.path.expand(source,"A>|<B","",0,5) yield path
return path
您将获得此路径作为输出:
apoc.path.expand
来自source
和-[:A]->
关系之后<-[:B]-
节点的呼叫。
请记住根据您使用的Neo4j版本安装APOC procedures。请查看version compatibility matrix。
答案 1 :(得分:1)
要在单个查询中表达这一点,需要一个常规路径查询,已经提出并accepted to openCypher,但它尚未实现。
我看到两种可能的解决方法。我使用此命令重新创建了您的示例,并为源节点添加了Source
标签:
CREATE (:Source)-[:A]->()-[:A]->()<-[:B]-()-[:A]->()
(1)插入具有相同方向的其他关系:
MATCH (s)-[:B]->(t)
CREATE (s)<-[:B2]-(t)
并使用此关系进行遍历:
MATCH p=(source)-[:A|:B2*]->()
RETURN p
(2)如你所说:
顺便说一句,我知道我能做到 - [:A |:B] - 但这不能解决我的问题,因为我不想跟随 - [:B] - &gt;和&lt; - [:A] - 。
您可以使用此方法首先获取潜在的路径候选者,然后手动检查关系的方向。当然,这是一项昂贵的操作,但您只需要在候选项上进行计算,这可能是一个很小的数据集。
MATCH p=(source:Source)-[:A|:B*]-()
WITH p, nodes(p) AS nodes, relationships(p) AS rels
WHERE all(i IN range(0, size(rels) - 1) WHERE
CASE type(rels[i])
WHEN 'A' THEN startNode(rels[i]) = nodes[i]
ELSE /* B */ startNode(rels[i]) = nodes[i+1]
END)
RETURN p
让我们分解一下这是如何运作的:
p
中,并使用nodes
和relationships
函数从中提取节点/关系列表。range
个索引(例如,如果有3个关系,则来自0, 1, 2
。)startNode
函数。例如,如果节点r
到n1
之间存在关系n2
,则路径将为<n1, r, n2>
。如果在传出方向上移动了r
,startNode(r)
将返回n1
,如果它在传入方向上移动,则startNode(r)
将返回n2
。使用type
函数检查关系的类型,并使用simple CASE
表达式来区分类型。WHERE
子句使用all
谓词函数检查所有:A
和:B
关系是否具有相应的路线。