我想显示一个树状子图,显示从单个节点开始的所有路径。大多数连接是双向的(此时2个边缘可能会更改为1个边缘而不是更好的性能)并且我有不同类型的关系。但是有一个特殊的节点和关系序列导致更多的循环,这个序列不应该显示在结果图中。
MATCH p=(n)-[r*0..4]-(m) WHERE n.CAT='a1' RETURN p
这个查询几乎解决了这个问题,但是我无法找到/创建正确的查询以使序列不在图中。深度仍然有限,因为深度[r*0..9]
neo4j网络应用程序停止响应(不是主要问题!我已经知道如何改进/修复此问题)并且需要一段时间才能停止数据库。序列正在创建最多的不需要的排列和大量可能的路径和循环。没有办法改变关系(除了使用1个边而不是2个,实际上它是双向的,但据我所知,操作应该仍然相同且不太复杂,正确的我知道我是否错了)节点因为有另一个起始节点,可能需要这种关系。
序列:
(x)-[:relation2]-(y)-[:relation2]-(z)
和x,y,z
在CAT='variable'
处具有相同的属性值。它始终是相同的关系和相同的属性。值和节点各不相同。
所有节点都是潜在的起始节点。
此外,查询必须非常快速地处理长路径(不同长度)有时分裂。大多数分裂将被忽略,序列被排除。深度必须是无限的。一旦查询忽略序列,结果路径将始终结束,并且不会出现" go"这条道路。
为了防止误会:
x,y,z1和z3共享相同的属性CAT(类别)=' a'和z2.CAT =' b'例如。
display
不显示和停止
(x)-[:relation2]-(y)
- [:relation2] - (z1)
(x)-[:relation2]-(y)-[:relation2]-(z2)
(x)-[:relation2]-(y)-[:relation1]-(z3)
x.CAT = y.CAT = z1.CAT = z3.CAT!= z2.CAT
查询的性能非常重要,这也是我这样做的原因,但首先我需要"简单"解决这个项目的进展。
提前多多感谢。
答案 0 :(得分:1)
为此,您应该创建自定义遍历。 在Neo4j中有一个API,请查看文档:{{3}}
要不遍历两个节点,您应该使用NODE_PATH
作为唯一性规则(在cypher中,它是RELATIONSHIP_PATH
唯一性以避免图形循环。)
干杯
答案 1 :(得分:0)
为此,您应该创建自定义遍历。在Neo4j中有一个API,请查看文档:{{3}}
要不遍历两个节点,您应该使用NODE_PATH作为唯一性规则(在cypher中,它是RELATIONSHIP_PATH唯一性以避免图形循环)。
正如@Tezra和@logisima所指出的那样,Traversal API是关键。但它没有完成独特性或任何复杂的事情。这终于打印出了我正在寻找的结果:
TraversalDescription td = graphDb.traversalDescription()
.depthFirst()
.uniqueness(Uniqueness.RELATIONSHIP_GLOBAL)
.evaluator( new Evaluator()
{
@Override
public Evaluation evaluate( final Path path )
{
Node parent=null,grandParent =null;
Relationship rel1=null,rel2=null;
int nCount=0,rCount=0;
if(path.length()>=2)
{
for(Node node : path.reverseNodes())
{
if(nCount==1)
parent = node;
if(nCount==2)
grandParent=node;
if(nCount>2)
break;
nCount++;
}
for(Relationship rel : path.reverseRelationships())
{
if(rCount==0)
rel1 = rel;
if(rCount==1)
rel2=rel;
if(rCount>1)
break;
rCount++;
}
}
if(path.length()<2)
{
return Evaluation.INCLUDE_AND_CONTINUE;
}
else if (path.length()>=2
&& rel1.isType(relType)
&& rel2.isType(relType)
&& path.endNode().getProperty("CATEGORY").toString().equals(parent.getProperty("CATEGORY").toString())
&& path.endNode().getProperty("CATEGORY").toString().equals(grandParent.getProperty("CATEGORY").toString()))
{
return Evaluation.EXCLUDE_AND_PRUNE;
}
else
{
return Evaluation.INCLUDE_AND_CONTINUE;
}
}
});
try ( Transaction tx = graphDb.beginTx() )
{
Traverser traverser = td.traverse(graphDb.getNodeById(id));
for ( Path path : traverser)
{
System.out.println(path.toString());
}
tx.success();
}
(特别感谢@Tezra让我按时走上正轨)
使用apoc的解决方案也应该是可能的,并且还避免了将图形恢复到neo4j的问题。