避免循环在 Neo4j 的图中列出给定长度的路径
Avoid cycles to list paths of given length in a graph in Neo4j
我有下图
我尝试在 Neo4j 中对上面的图进行建模,这样对于任何重复的节点(比如 A),节点上的 属性 'count' 会递增以反映 A 的出现次数。同样,对于任何重复关系(比如 A->B),都会更新 属性 'frequency'。
图形的 Neo4j 控制台已实现 here。
我以上述方式对图表建模,牢记我可以跟踪每个节点和每个单独转换的出现次数。
我要求的下一部分是跟踪所有 3 节点路径,这是我发出的查询,其输出在 Neo4j 控制台中可见 -
MATCH (n)-[]->(m)-[]->(p) return n.name+' - '+m.name+' - '+p.name as NewName
但是,我想要的输出是 -
A - B - C
B - D - A
D - A - B
B - D - E
E - B - C
D - E - B
A - B - D
但由于节点和关系是唯一的,因此还报告了一种额外的组合。
E - B - D
问题
我需要在图表中更改什么 setup/query 以便仅报告列出的 7 个组合而不是 8 个组合?
有没有办法也计算这种 3 节点路径的频率?
我可以创建多个 CYPHER 脚本来实现此目的。话虽这么说,CYPHER 脚本是作为更大工作流程的一部分自动生成的,我想避免手动输入 n 节点路径及其频率。
您应该更改数据模型。您不需要计算和更新 count
和 frequency
属性;相反,它们可以直接从适当的数据模型中获得。
例如,让我们使用备用数据模型来创建示例数据。每个命名节点都表示为 Foo
节点一次。 Foo
节点的每次使用都由一个 Bar
节点表示,该节点通过 FOR
关系引用其 Foo
节点。 Bar
个节点通过 NEXT
个关系链接在一起。
创建示例数据
CREATE (a:Foo {name: 'A'}), (b:Foo {name: 'B'}), (c:Foo {name: 'C'}), (d:Foo {name: 'D'}), (e:Foo {name: 'E'})
CREATE (a1:Bar)-[:FOR]->(a), (b1:Bar)-[:FOR]->(b),
(a1)-[:NEXT]->(b1)
CREATE (c1:Bar)-[:FOR]->(c),
(b1)-[:NEXT]->(c1)
CREATE (d1:Bar)-[:FOR]->(d),
(b1)-[:NEXT]->(d1)
CREATE (a2:Bar)-[:FOR]->(a),
(d1)-[:NEXT]->(a2)
CREATE (b2:Bar)-[:FOR]->(b),
(a2)-[:NEXT]->(b2)
CREATE (e1:Bar)-[:FOR]->(e),
(d1)-[:NEXT]->(e1)
CREATE (b3:Bar)-[:FOR]->(b),
(e1)-[:NEXT]->(b3)
CREATE (c2:Bar)-[:FOR]->(c),
(b3)-[:NEXT]->(c2);
获取每个Foo节点被使用的次数:
MATCH (f:Foo)<--() RETURN f, COUNT(*) AS count;
获取每对Foo节点依次使用的次数:
MATCH (f1:Foo)<-[:FOR]-()-[:NEXT]->()-[:FOR]->(f2:Foo)
RETURN f1, f2, COUNT(*) AS count;
获取Foo节点的每个三元组按顺序使用的次数:
MATCH (f1:Foo)<-[:FOR]-()-[:NEXT]->(b1)-[:FOR]->(f2:Foo), (b1)-[:NEXT]->(b2)-[:FOR]->(f3:Foo)
RETURN f1, f2, f3, COUNT(*) as count;
这是最后一次查询的结果,其中显示了所有 7 个有效的三元组及其出现的次数:
+----------------------------------------------------------------------+
| f1 | f2 | f3 | count |
+----------------------------------------------------------------------+
| Node[3]{name:"D"} | Node[4]{name:"E"} | Node[1]{name:"B"} | 1 |
| Node[1]{name:"B"} | Node[3]{name:"D"} | Node[4]{name:"E"} | 1 |
| Node[4]{name:"E"} | Node[1]{name:"B"} | Node[2]{name:"C"} | 1 |
| Node[3]{name:"D"} | Node[0]{name:"A"} | Node[1]{name:"B"} | 1 |
| Node[1]{name:"B"} | Node[3]{name:"D"} | Node[0]{name:"A"} | 1 |
| Node[0]{name:"A"} | Node[1]{name:"B"} | Node[3]{name:"D"} | 1 |
| Node[0]{name:"A"} | Node[1]{name:"B"} | Node[2]{name:"C"} | 1 |
+----------------------------------------------------------------------+
我有下图
我尝试在 Neo4j 中对上面的图进行建模,这样对于任何重复的节点(比如 A),节点上的 属性 'count' 会递增以反映 A 的出现次数。同样,对于任何重复关系(比如 A->B),都会更新 属性 'frequency'。
图形的 Neo4j 控制台已实现 here。
我以上述方式对图表建模,牢记我可以跟踪每个节点和每个单独转换的出现次数。
我要求的下一部分是跟踪所有 3 节点路径,这是我发出的查询,其输出在 Neo4j 控制台中可见 -
MATCH (n)-[]->(m)-[]->(p) return n.name+' - '+m.name+' - '+p.name as NewName
但是,我想要的输出是 -
A - B - C
B - D - A
D - A - B
B - D - E
E - B - C
D - E - B
A - B - D
但由于节点和关系是唯一的,因此还报告了一种额外的组合。
E - B - D
问题
我需要在图表中更改什么 setup/query 以便仅报告列出的 7 个组合而不是 8 个组合?
有没有办法也计算这种 3 节点路径的频率?
我可以创建多个 CYPHER 脚本来实现此目的。话虽这么说,CYPHER 脚本是作为更大工作流程的一部分自动生成的,我想避免手动输入 n 节点路径及其频率。
您应该更改数据模型。您不需要计算和更新 count
和 frequency
属性;相反,它们可以直接从适当的数据模型中获得。
例如,让我们使用备用数据模型来创建示例数据。每个命名节点都表示为 Foo
节点一次。 Foo
节点的每次使用都由一个 Bar
节点表示,该节点通过 FOR
关系引用其 Foo
节点。 Bar
个节点通过 NEXT
个关系链接在一起。
创建示例数据
CREATE (a:Foo {name: 'A'}), (b:Foo {name: 'B'}), (c:Foo {name: 'C'}), (d:Foo {name: 'D'}), (e:Foo {name: 'E'})
CREATE (a1:Bar)-[:FOR]->(a), (b1:Bar)-[:FOR]->(b),
(a1)-[:NEXT]->(b1)
CREATE (c1:Bar)-[:FOR]->(c),
(b1)-[:NEXT]->(c1)
CREATE (d1:Bar)-[:FOR]->(d),
(b1)-[:NEXT]->(d1)
CREATE (a2:Bar)-[:FOR]->(a),
(d1)-[:NEXT]->(a2)
CREATE (b2:Bar)-[:FOR]->(b),
(a2)-[:NEXT]->(b2)
CREATE (e1:Bar)-[:FOR]->(e),
(d1)-[:NEXT]->(e1)
CREATE (b3:Bar)-[:FOR]->(b),
(e1)-[:NEXT]->(b3)
CREATE (c2:Bar)-[:FOR]->(c),
(b3)-[:NEXT]->(c2);
获取每个Foo节点被使用的次数:
MATCH (f:Foo)<--() RETURN f, COUNT(*) AS count;
获取每对Foo节点依次使用的次数:
MATCH (f1:Foo)<-[:FOR]-()-[:NEXT]->()-[:FOR]->(f2:Foo)
RETURN f1, f2, COUNT(*) AS count;
获取Foo节点的每个三元组按顺序使用的次数:
MATCH (f1:Foo)<-[:FOR]-()-[:NEXT]->(b1)-[:FOR]->(f2:Foo), (b1)-[:NEXT]->(b2)-[:FOR]->(f3:Foo)
RETURN f1, f2, f3, COUNT(*) as count;
这是最后一次查询的结果,其中显示了所有 7 个有效的三元组及其出现的次数:
+----------------------------------------------------------------------+
| f1 | f2 | f3 | count |
+----------------------------------------------------------------------+
| Node[3]{name:"D"} | Node[4]{name:"E"} | Node[1]{name:"B"} | 1 |
| Node[1]{name:"B"} | Node[3]{name:"D"} | Node[4]{name:"E"} | 1 |
| Node[4]{name:"E"} | Node[1]{name:"B"} | Node[2]{name:"C"} | 1 |
| Node[3]{name:"D"} | Node[0]{name:"A"} | Node[1]{name:"B"} | 1 |
| Node[1]{name:"B"} | Node[3]{name:"D"} | Node[0]{name:"A"} | 1 |
| Node[0]{name:"A"} | Node[1]{name:"B"} | Node[3]{name:"D"} | 1 |
| Node[0]{name:"A"} | Node[1]{name:"B"} | Node[2]{name:"C"} | 1 |
+----------------------------------------------------------------------+