我想计算给定起始节点每种类型的关系。我构建了两个可能的查询来实现这一目标,但我不知道在处理大量关系时哪个查询会更有效。
count()
MATCH (n) WHERE id(n) = 0
CALL {
WITH n
MATCH (n)<-[r]-()
RETURN '<'+TYPE(r) AS type, COUNT(r) AS count
UNION ALL
WITH n
MATCH (n)-[r]->()
RETURN TYPE(r)+'>' AS type, COUNT(r) AS count
}
RETURN type, count
结果:
╒════════════╤═════╕
│type │count│
╞════════════╪═════╡
│"<ACTED_IN" │5 │
├────────────┼─────┤
│"<PRODUCED" │1 │
├────────────┼─────┤
│"<DIRECTED" │2 │
└────────────┴─────┘
apoc.node.relationship.types()
和 type, apoc.node.degree.[in|out]()
MATCH (n) WHERE id(n) = 0
WITH n, apoc.node.relationship.types(n) AS types
CALL {
WITH n, types
UNWIND types as type
RETURN '<'+type AS type, apoc.node.degree.in(n, type) as count
UNION ALL
WITH n, types
UNWIND types as type
RETURN type+'>' AS type, apoc.node.degree.out(n, type) as count
}
RETURN type, count
结果:
╒════════════╤═════╕
│type │count│
╞════════════╪═════╡
│"<ACTED_IN" │5 │
├────────────┼─────┤
│"<DIRECTED" │2 │
├────────────┼─────┤
│"<PRODUCED" │1 │
├────────────┼─────┤
│"ACTED_IN>" │0 │
├────────────┼─────┤
│"DIRECTED>" │0 │
├────────────┼─────┤
│"PRODUCED>" │0 │
└────────────┴─────┘
第二个查询返回空关系类型的行,但这可以忽略。
我只能分析第一个仅密码查询,因为无法分析像 APOC 这样的自定义过程。
因为您只计算单个节点的关系,所以任一版本都将花费几毫秒,因此性能并不相关。只有在对许多节点进行计数的情况下,您才会考虑它。无论如何,在没有分析的情况下,最好的方法是实际测量它。
我比较了以下 Cypher 和 APOC 版本的不同数量的关系(实际的
MATCH
重复计数,但这并不重要):
密码
MATCH (n)-[r]-()
RETURN
CASE
WHEN (startNode(r) = n) THEN type(r) + '>'
ELSE '<' + type(r)
END AS type,
count(r) AS count
APOC
MATCH (n)
CALL {
WITH n
WITH n, apoc.node.relationship.types(n) AS types
CALL {
WITH n, types
UNWIND types as type
RETURN '<'+type AS type, apoc.node.degree.in(n, type) as count
UNION ALL
WITH n, types
UNWIND types as type
RETURN type+'>' AS type, apoc.node.degree.out(n, type) as count
}
RETURN type, count
}
RETURN type, sum(count)
这是一个比较(基于本地运行数据库):
APOC 查询可能有更高效的版本,但无论如何,这里的 Cypher 更快。