图分组
大型图通常难以理解或可视化。
表格结果可以聚合以提供概览,例如在图表中显示总和、计数等。
按属性值将节点分组到虚拟节点中,有助于在图可视化中实现同样的效果。
这样做时,这些组之间的关系也会被聚合,因此您只能看到汇总信息。
此功能灵感来源于 Martin Junghanns 在为 Gradoop 图处理系统提供的 Grouping Demo 中的工作。
基本上,您可以使用任何 (entity)<-->(entity)
图进行分组,图投影支持正在路线图中。
这是一个使用数据集的示例,数据集来源于 :play movies
。
MATCH (n)
SET n.century = toInteger(coalesce(n.born,n.released)/100) * 100;
CALL apoc.nodes.group(['Person','Movie'],['century']);

有时 UI 在处理分组的返回值(节点列表和关系列表)时可能出现问题,这时运行以下命令可能会有所帮助
|
用法
CALL apoc.nodes.group(labels,properties, [grouping], [config])
唯一必需的参数是一个标签列表(也可以是 ['*']
)以及一个用于分组的属性名称列表(适用于关系/节点)。
您还可以选择提供按字段分组的操作符以及一些配置选项。
分组操作符
对于分组操作符,您以这种形式提供一个每字段操作的 MAP
:{fieldName: [operators]}
一个用于节点的映射,一个用于关系的映射:[{nodeOperators},{relOperators}]
可能的操作符
-
count_*
-
count
-
sum
-
min/max
-
avg
-
collect
默认值是:[{`*`:"count"},{`*`:"count"}]
,这只计算节点和关系。
配置
配置中有更多选项
选项 | 默认值 | 描述 |
---|---|---|
|
|
在结果图中显示自循环关系 |
|
|
在结果图中显示孤立节点 |
|
|
限制最大节点数 |
|
|
限制最大关系数 |
|
|
限制每个节点的关系数量 |
|
|
一个按属性值进行的最小/最大过滤器,例如 |
|
|
要包含的关系类型。默认是包含所有关系类型。可以是类型列表或单个类型。 |
|
|
要排除的关系类型。默认是不排除任何关系类型。可以是类型列表或单个类型。 |
filter
配置选项是一个 MAP
,形式为 {Label/TYPE.operator_property.min/max: number}
,其中 Label/TYPE.
前缀是可选的。
例如,您可以筛选出分组中最小年龄为 21 岁的人:Person.min_age.min: 21
,或者最多拥有 10 个共同的 KNOWS
关系:KNOWS.count_*.max:10
。
示例
CREATE
(alice:Person {name:'Alice', gender:'female', age:32, kids:1}),
(bob:Person {name:'Bob', gender:'male', age:42, kids:3}),
(eve:Person {name:'Eve', gender:'female', age:28, kids:2}),
(graphs:Forum {name:'Graphs', members:23}),
(dbs:Forum {name:'Databases', members:42}),
(alice)-[:KNOWS {since:2017}]->(bob),
(eve)-[:KNOWS {since:2018}]->(bob),
(alice)-[:MEMBER_OF]->(graphs),
(alice)-[:MEMBER_OF]->(dbs),
(bob)-[:MEMBER_OF]->(dbs),
(eve)-[:MEMBER_OF]->(graphs)
CALL apoc.nodes.group(['*'],['gender'],
[{`*`:'count', age:'min'}, {`*`:'count'} ])
节点 | 关系 | 节点 | 关系 |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
请注意,此查询在 Neo4j Browser 的“图”模式下不起作用,仅在“表格”模式下(或在 cypher-shell 中)起作用,因为 Forum
没有 gender
属性,所以在 node
结果中会出现一个不受支持并返回 TypeError
的 "gender": null
属性。相反,下面的查询在“图”模式下也能正常工作
CALL apoc.nodes.group(
['Person'],['gender'],
[{`*`:'count', kids:'sum', age:['min', 'max', 'avg'], gender:'collect'},
{`*`:'count', since:['min', 'max']}]);
大型示例
WITH ["US","DE","UK","FR","CA","BR","SE"] AS tld
UNWIND range(1,1000) AS id
CREATE (u:User {id:id, age : id % 100, female: rand() < 0.5, name: "Name "+id, country:tld[toInteger(rand()*size(tld))]})
WITH collect(u) AS users
UNWIND users AS u
WITH u, users[toInteger(rand()*size(users))] AS u2
WHERE u <> u2
MERGE (u)-[:KNOWS]-(u2);
CALL apoc.nodes.group(['*'], ['country'])
YIELD node, relationship return *

CALL apoc.nodes.group(['*'], ['country'], null,
{selfRels:false, orphans:false,
filter:{`User.count_*.min`:130,`KNOWS.count_*.max`:200}})
YIELD node, relationship return *

要在 Neo4j Browser 中可视化此结果,最好有一个自定义的图样式表 (GRASS),它可以使用一些聚合来渲染分组属性。
node {
diameter: 50px;
color: #A5ABB6;
border-color: #9AA1AC;
border-width: 2px;
text-color-internal: #FFFFFF;
font-size: 10px;
}
relationship {
color: #A5ABB6;
shaft-width: 3px;
font-size: 8px;
padding: 3px;
text-color-external: #000000;
text-color-internal: #FFFFFF;
caption: '{count_*}';
}
node.Country {
color: #68BDF6;
diameter: 80px;
border-color: #5CA8DB;
text-color-internal: #FFFFFF;
caption: '{country} ({count_*})';
}