我创建了以下基本图表:
CREATE (:NodeType1 {prop1:'value1'})-[:RelType1 {prop2:'value2'}]->(:NodeType2 {prop3:'value3'})-[:RelType2 {prop4:'value4'}]->(:NodeType3 {prop5:'value5'})-[:RelType3 {prop6:'value6'}]->(:NodeType4 {prop7:'value7'})
CREATE (:NodeType1 {prop1:'value8'})-[:RelType1 {prop2:'value9'}]->(:NodeType2 {prop3:'value10'})-[:RelType2 {prop4:'value11'}]->(:NodeType3 {prop5:'value12'})-[:RelType3 {prop6:'value13'}]->(:NodeType4 {prop7:'value14'})
MATCH path=(n:NodeType1 {prop1:'value1'})-[*]->(m:NodeType4 {prop7:'value7'})
CREATE (n)-[:RelType1 {prop2:'value15'}]->(:NodeType2 {prop3:'value16'})-[:RelType2 {prop4:'value17'}]->(:NodeType3 {prop5:'value18'})-[:RelType3 {prop6:'value19'}]->(m)
图表如下所示:
当我运行以下密码时:
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)-[:RelType2]->(c)-[:RelType3]->(d)
RETURN count(nodes(path))
我得到2
作为输出。似乎nodes()
实际上并不返回路径中的数字节点,而只返回返回结果中的行数,因为如果我返回path
:
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)-[:RelType2]->(c)-[:RelType3]->(d)
RETURN path
我在返回的结果中得到两行:
现在我猜测在使用Neo4J遍历API进行遍历时如何获得相同的输出。我在cypher中获得了许多唯一节点,如下所示:
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)-[:RelType2]->(c)-[:RelType3]->(d)
RETURN size(collect(distinct a))+size(collect(distinct b))+size(collect(distinct c))+size(collect(distinct d))
以上查询正确返回6
。
通过在路径扩展器内部使用静态计数器,可以在遍历API中完成相同的操作,每次调用expand()
时都会增加。 (有没有更好的方法呢?)
public class MyPathExpander implements PathExpander{
static int nodeCount = 0;
@Override
public Iterable expand(Path path, BranchState state) {
Node lastNode = path.endNode();
nodeCount++; //**increment the count of nodes visited
if(lastNode.hasLabel(MyLabels.NodeType1))
return lastNode.getRelationships(MyRelations.RelType1, Direction.OUTGOING);
else if (lastNode.hasRelationship(MyRelations.RelType1, Direction.INCOMING))
return lastNode.getRelationships(MyRelations.RelType2, Direction.OUTGOING);
else if (lastNode.hasRelationship(MyRelations.RelType2, Direction.INCOMING))
return lastNode.getRelationships(MyRelations.RelType3, Direction.OUTGOING);
else if (lastNode.hasRelationship(MyRelations.RelType3, Direction.INCOMING))
return null;
return null;
}
}
但是,我无法想到在使用Traversal API(相当于上面的RETURN count(nodes(path))
)时会告诉我在遍历期间遵循的唯一路径数量的方式。我怎样才能做到这一点?遍历API是不可能的?
PS:通过唯一路径,我指的是遍历时访问的节点顺序的唯一排列。例如,所有a-b-c
,a-c-b
和a-b-c-d
都是唯一的。
答案 0 :(得分:0)
此查询不返回唯一路径的计数,但所有路径的计数都按查询返回:
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)
-[:RelType2]->(c)-[:RelType3]->(d)
RETURN count(nodes(path))
如果要计算查询中唯一节点的数量,可以这样做:
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)
-[:RelType2]->(c)-[:RelType3]->(d)
UNWIND nodes(path) AS N
RETURN count(distinct N)
计算唯一路径数量的一种方法是(对于每个路径计算其唯一指纹,通过遍历API重复将不难:)
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)
-[:RelType2]->(c)-[:RelType3]->(d)
WITH path,
REDUCE(acc="", x in nodes(path) | acc + id(x)) +
REDUCE(acc="", x in rels(path) | acc + id(x)) as uniID
RETURN count(distinct uniID)