这个问题虽然在文档 超级节点(稠密点) - NebulaGraph Database 手册 有所涉及,在这里再结合下相关的帖子,汇总下相关信息。
超级节点的查找
首先要解决的是如何判断这是一个超级节点,这里涉及到如何统计某个点的出入度。
根据 如何在 Nebula Graph 中计算结点的出入度 贴中 nicole 的建议,你可以使用 nebula-algorithm 借助图计算来计算点的出入度。可以参考代码:nebula-algorithm/example/src/main/scala/com/vesoft/nebula/algorithm/DegreeStaticExample.scala at 20573b33096712a59a36447723af41c7ee068824 · vesoft-inc/nebula-algorithm · GitHub
或者根据 nGQL 的语法,比如:
# 特定点的出入度
MATCH (v1)-[e]->(v2) WHERE id(v1) == "xxx" RETURN count(e);
# 大于指定出入度的所有点
MATCH (:tag1)<-[:e]-(v:tag2)-[:e]->(:tag3)
RETURN distinct v
MATCH (v:tag1)-[:e]->(:tag2)
where size((v)-[:e]->())>2
RETURN distinct v
找寻到超级节点。
超级节点的处理
这里直接引用文档内容:
数据库端的常见办法
应用端的常见办法
根据业务意义,将一些超级顶点拆分:
-
删除多条边,合并为一条
例如,一个转账场景:(账户 A)-[转账]->(账户 B)
。每次转账
建模为一条 AB 之间的边
,那么(账户 A)
和(账户 B)
之间会有着数万十次转账的场景。按日、周、或者月为粒度,合并陈旧的转账明细。也就是批量删除陈旧的边,改为少量的边“月总额”和“次数。而保留最近月的转账明细。 -
拆分相同类型的边,变为多种不同类型的边
例如,(机场)<-[depart]-(航班)
场景,每个架次航班的离港,都建模为一条航班和机场之间的边。那么大型机场的离港航班会极多。根据不同的航空公司
将depart
这个 Edge type 拆分更细的 Edge type,如depart_ceair
,depart_csair
等。在查询(图遍历)时,指定离港的航空公司。 -
切分顶点本身
例如,对于(人)-[借款]->(银行)
的借款网络,某大型银行 A 的借款次数和借款人会非常的多。可以将该大行节点 A 拆分为多个相关联的子节点 A1、A2、A3,(人 1)-[借款]->(银行 A1), (人 2)-[借款]->(银行 A2), (人 2)-[借款]->(银行 A3); (银行 A1)-[属于]->(银行 A), (银行 A2)-[属于]->(银行 A), (银行 A3)-[属于]->(银行 A).
这里的 A1、A2、A3 既可以是 A 真实的三个分行(例如北京、上海、浙江),也可以是三个按某种规则设立的虚拟分行,例如按借款金额划分
A1: 1-1000, A2: 1001-10000, A3: 10000+
。这样,查询时对于 A 的任何操作,都转变为为对于 A1、A2、A3 的三次单独操作。