提问参考模版:
nebula 版本:v3.4.1
部署方式:分布式
安装方式: RPM
是否上生产环境:Y
硬件信息
问题的具体描述
需求: 找出对外投资路径中企业是非注销状态,最多展示20层
需求: 找出对外投资路径中存在公司不为 "注销"状态的路径,最多展示20层。
所以为了实现这个需求,存在的问题是:
subgraph 只是目的点过滤,这个就不太符合需求了。因为路径的中间点有可能是满足的
是要返回全部路径的
那这个和subgraph 一样,应该也是不太符合需求了
这个需求该怎么用语句表达呢?
目前有两种想法:
用Get Subgraph
GET SUBGRAPH WITH PROP 20 STEPS FROM 815677140545765099 OUT Invest YIELD VERTICES as nodes, Edges as rels
但是这个问题是语句中如何过滤 Company.shortstatus != "注销"的路径呢?
用Match 或者Go 总觉得表达上有缺失, 同时也担心有性能问题
match p=(v:Company)-[r:Invest*1..20]->(dst) where id(v)==815677140545765099 and dst.Company.shortstatus!="注销" return p
go 1 To 20 STEPS FROM 815677140545765099 OVER Invest where properties($$).shortstatus!="注销" yield DISTINCT dst(edge) as id
这个go 语句的想法是先拿到终点,再并发用FIND PATH 找路径
现在的问题是:
subgraph 可以在语句中过滤吗? 业务上过滤20层数据感觉会很多
match 和 go 的表达虽然是用了不定长路径,但都是终点满足条件,不确定这个语义上是否符合需求
我初始以为 第二个方法里面match 和go 的语义应该是相同的,但是测试后发现结果不一致
不好意思,需求表达不够准确,
需求: 找出对外投资路径中企业是非注销状态,最多展示20层
找出对外投资路径中存在公司
为 "在业"状态的路径,最多展示20层。
所以为了实现这个需求,存在的问题是:
subgraph 只是目的点过滤,这个就不太符合需求了。因为路径的中间点有可能是满足的
是要返回全部路径的
那这个和subgraph 一样,应该也是不太符合需求了
这个需求该怎么用语句表达呢?
yee
2023 年8 月 14 日 05:51
5
GET SUBGRAPH 支持对图中经过的点的属性做过滤的,可以直接在 WHERE 中加过滤:
GET SUBGRAPH WITH PROP 20 STEPS
FROM 815677140545765099 OUT Invest
WHERE $$.Company.shortstatus != "注销"
YIELD VERTICES as nodes, Edges as rels
这个只是最终的叶子节点吧? 中间路径上的满足条件的也希望保留的
yee
2023 年8 月 14 日 07:22
7
是对每一步都进行过滤的,可以通过执行计划上看出来:
哦哦,想了想也不太满足。
现在这个是ALL(path node), 其实我需要的是Any(path node) 存在一个满足条件即可。
也想过把把属性放到边上,也有这个问题
yee
2023 年8 月 14 日 07:49
9
我感觉两个好像是等价的
任意一条路径上经过此类顶点就排除该路径,不就相当于先把此类顶点都排除之后找路径。暂时没想到什么路径不经过该类型的顶点,同时又不在后者的子图上。感觉满足条件的路径肯定和后者的子图是联通的,所以拿子图肯定能将该路径囊括进来。
Reid00
2023 年8 月 14 日 07:54
10
你看这么两个路径:
A -[Invest] ->B -[Invest]->C-[Invest]->D
A -[Invest] ->F -[Invest]->G-[Invest]->H
B shortstatus 是在业,C在注销
F,G,H shortstatus 是注销
如果用shortstatus != 注销 是不是 1 也会被过滤掉。 但是1其实是满足条件的。
yee
2023 年8 月 14 日 08:10
11
是说路径上允许一个顶点满足注销的条件?不是说路径上只要有一个点满足注销的条件,该路径就过滤?
如果是上述1的表达,那确实不能把所有的都过滤。这只能是在找路径的过程中检查当前路径是否满足条件了
Reid00
2023 年8 月 14 日 08:14
12
路径上只要有一个点满足不
注销的条件,该路径就该保留。
目前是这样的需求。怎么可以实现这样的查询需求吗?
yee
2023 年8 月 14 日 08:31
13
Reid00:
可以
哦哦,我理解错了。
有试过先找所有的路径然后再过滤掉全是注销的路径的做法吗?
yee
2023 年8 月 14 日 08:58
15
get subgraph 只能返回点边的集合,不知道现在如何处理的路径?有一种做法就是通过 subgraph 拿到所有的 20 跳的终点,然后 pipe 给 find all path 来找路径,再进行过滤。
或者通过图计算的方式找路径,这种偏向深度的查询可以用图计算的方式并行的迭代计算。
Reid00
2023 年8 月 15 日 02:33
17
昨天做了压测,用get subgraph 获取20层,然后业务上遍历做过滤。性能较差,平均2s了。
有些超时(>10s)的看了下返回的数据量大小,过滤前,sum(size($-.v))=114023, sum(size($-.e))=135395, 这个也没想象的那么多。
请问目前这个有什么较好的查询语句写法吗?
yee
2023 年8 月 15 日 03:09
18
性能差的原因是 get subgraph 这块时间就超过限制了,还是加上了业务层拼接的代码?
因为现在的过滤需要走完 20 步才能终止,无法提前结束,所以现有的过滤方法都失效了。
另外的一个想法是,用 go 走 20 步,获取到所有的终点,然后用 find all path 找起点到这些终点的所有的路径。find all path 的并发实现比 subgraph 好点,不知道这样都在服务端执行会不会比之前的服务端+客户端的总时间更好些,这个具体还要你们来验证。
不过总体而言,你们的这个场景还是对我们的启发还是很大的,我们会在新版本中将相关的实现迭代到新的框架中。非常感谢!
cc @MuYi
1 个赞
Reid00
2023 年8 月 15 日 03:37
19
只是get subgraph, 业务层的拼接耗时目前没有算进来。
我之前有想过是不是数据量太大,传输耗时也比较久。但是看起来超时的数据量没有太大(10w) 左右。
第二个想法,有想过,但是具体实现上,这个过滤怎么写呢? 我现在的问题在于这个过滤条件是对所有层级上做Any,不是ALL,这个导致我不知道具体怎么写
MuYi
2023 年8 月 15 日 04:01
20
想先问下,现在match 20跳,不做任何过滤的话,效率大概多高?能否满足时间需求?如果可以满足的话可以考虑用reduce来做过滤
match p=(v:Company)-[r:Invest*1…20]->(dst) where id(v)==815677140545765099 return p
这个的效率