如何统计图中每一个节点的二度出度值呢?

nebula graph版本:3.3.0
nebula studio版本:3.5.0
spark版本:2.4
部署方式:分布式
硬盘:机械硬盘
是否为线上版本:N


由于业务场景需要,需要统计节点重要性,该重要性判断标准是:在子图中,统计节点二度传播范围内的关系连接总数,且统计二度传播时,关系量必须比一度关系量多时才计入总数。
例如下图中:

节点1001的一度出度为2,二度出度为3,则1001的重要度为5;
而节点1124的一度出度为2,二度出度为1(1777–>1888),1<2,则节点1124的重要度不计算。

各位大佬,请问下,有没有现成的算法支持上述度数统计呢?或者不要求二度关系比一度多,只统计所有节点二度以内的所有出度数量呢?
感谢!

没有,不过可以在nebula-algorithm上自定义,实现比较简单,可以参考这个算法nebula-algorithm/DegreeStaticAlgo.scala at master · vesoft-inc/nebula-algorithm · GitHub

如果用python实现的话,读取出的子图时dataframe形式,有两列:src和dst。
那我是不是构造两层for循环,第一层循环每一个src中的节点,记为 i,第二层循环为 i 对应的每一个二度节点。
这样两层循环的话,好像有点耗时。。。

你只需要利用nebula-algorithm把nebulaGraph的数据读出来构造成graphx的Graph,然后

  1. 计算所有节点度
  2. 将所有节点的度 按照入边方向发送给邻居, 当某节点收到来自邻居的度,进行汇总。
  3. 这样得到的结果就是一个点的二度出度值
1 个赞

可以考虑用 ngql 描述。比如:

  1. 输出类型 A 中所有节点二度以内的出度
MATCH (v:A)
RETURN size((v)-->()) AS out_degree1, size((v)-->()-->()) AS out_degree2
  1. 输出二度关系比一度多的点
MATCH (v:A)
WHERE size((v)-->()-->())  > size((v)-->()) 
RETURN v
1 个赞

我了解degreestatic算法输入参数如下:
image
那我其实将step输入2,type输入out就可以计算节点的二度出方向度的重要性。
您可以再指点下,我如何修改源码使得二度出度关系数 > 一度出度关系数吗? :heart:

你可以先计算出一度,然后将节点的一度值作为点的属性,然后计算二度值,最后对数据进行一次过滤,过滤条件就是几点两个属性的比较。

1 个赞

我试过了! 这个可以的!这个挺便捷哈 !谢谢!!

有道理! 这两种方法可以都试试!
感谢您!

您好! 我在basketballplayer数据集上验证了这两个统计度数的语句,是可行的。
我在ldbc数据集上,做完社区划分后,执行度数统计:

MATCH (v:partition) where v.partition.louvain==34 RETURN id(v) as id,size((v)-->()) AS out_degree1, size((v)-->()-->()) AS out_degree2

结果总出不来(猜测可能因为数据大)。
我想问下,我是否可以先根据属性取出子图(louvain==34),然后在子图上进行您发的度数统计呢?

1 个赞

目前还不支持。
可以尝试把 pattern 写在 MATCH 里边(louvain 这个属性上需要建立索引):

MATCH (v:partition)-->()
WHERE v.partition.louvain==34
RETURN id(v) AS id, count(*) AS out_degree1

这个我试过了,统计一度的时候,可以出结果,但是如果统计二度的,就特别慢,总是报错:
E_RPC_FAILURE(-3)或者AssertionError: Execution had been killed
我提了问题 python连接nebula时,查询语句返回不了结果:result ResultSet(None) - #3,来自 user82, 也尝试将session_idle_timeout_secs调大了,还是不行。

汤圆老师您好!
我利用basketballplayer数据集,指定follow关系,然后将degreestatic算法中参数设置如下:


在输出结果中,我查看了一个csv的数据,如下:
image
为了验证,我用ngql语句查询:

MATCH (v:player)-[e:follow]-(v2)-[e1:follow]-(v3) where id(v)=='103' return v,e,v2,e1,v3

结果为


我感觉不太匹配啊。。

我又查了个:
c566efcb101834505a1cd0809871797

用ngql语句验证:

MATCH (v:player)-[e:follow]-(v2)-[e1:follow]-(v3) where id(v)=='126' return v,e,v2,e1,v3


出度为1,是指126–>116–>141吗?也就是2跳都是出边就计数为1?但是103节点入边数量不是1。。
汤圆大大 求助~~

结果是对的呀,你看103这个节点,它有两条边连接,所以度是2, 两条边中一个是出边一个是入边,所以入度和出度分别是1.

算法结果中,degree是总度,inDegree是入度,outDegree是出度。 对于每一个节点,degree的值=inDegree+outDegree

但是我前面参数中,step设置的是2,应该计算2度的度数吧?为什么只计算1度的呢

你在哪里设置的step啊, algorithm的度统计算法没有参数啊

啊。。。我好像之前是自己加的。。我看说明文档中的参数如下:


应该是手动自己在配置文件中加了。。

  1. 那algorithm中的degreestatic算法,默认计算一度的degree吗?
  2. 我想统计二度出边关系数时,需要用Analytics包吗?

除了通过nGQL语句进行图查询,有没有其他方法可以计算节点一度和二度的值呢? :grimacing:

您好 我使用上述方式统计二度出边数量, 总是报内存溢出或服务器连接不上等错误:


请问还有没有其它方式去统计二度出边数量呢?比如lookup方式等。
感谢!

数据量很大的话是有可能 OOM 的。
可以限制一下点边类型:

MATCH (v:partition)-[:E]->(v2:partition)-[:E]->(v3:partition)
WHERE v.partition.louvain==94
RETURN id(v) AS id, count(*) AS out_degree2

LOOKUP 的话:

LOOKUP ON partition WHERE partition.louvain==94 YIELD id(vertex) AS id 
| GO 2 STEPS FROM $-.id OVER E YIELD $-.id AS src, id($$) AS dst
| YIELD $-.src AS id, count($-.dst) AS out_degree2
3 个赞