match with 字句改写

提问参考模版:

  • nebula 版本:nebula3.4.1
  • 部署方式: 分布式
  • 安装方式:RPM
  • 是否上生产环境:Y
  • 硬件信息
    • 磁盘( 推荐使用 SSD)
    • CPU、内存信息
  • 问题的具体描述
    在neo4j 的业务种有个语句如下
CALL { MATCH p = (self:Company)<-[sr:Invest|Legal]-(target) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 RETURN target, p, 'C' AS nodeType, 1 AS orderWeight UNION MATCH p = (self:Company)<-[sr:FinalBenefit]-(target:Company) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 AND sr.percent >= 5 RETURN target, p, 'BE5' AS nodeType, 5 AS orderWeight UNION MATCH p = (self:Company)<-[sr:FinalBenefit]-(target:Person) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 AND sr.percent >= 5 RETURN target, p, 'BP5' AS nodeType, 5 AS orderWeight UNION MATCH p = (self:Company)<-[sr:Employ]-(target:Person) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 RETURN target, p, 'DJG' AS nodeType, 7 AS orderWeight UNION MATCH p = (self:Company)-[sr:Invest]->(target:Company) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 RETURN target, p, 'HE' AS nodeType, 4 AS orderWeight }  WITH target, p, nodeType, orderWeight RETURN target AS target, collect(p) AS path, collect(nodeType) AS nodeType, min(orderWeight) AS orderWeight, CASE target.status WHEN 'Yes' THEN 0 WHEN 'No' THEN 0 WHEN '' THEN 0 WHEN 'Yes_1' THEN 1 WHEN 'xx' THEN 1 WHEN 'xxx' THEN 10 WHEN 'xxxx' THEN 10 WHEN '***' THEN 11 WHEN '*' THEN 11 ELSE 8 END AS status ORDER BY status, orderWeight SKIP 0 LIMIT 100

语句是若干个match 语句UNION 到一起(我这边删除了一半的语句),在neo4j 种有call {}最后用with 拼到一起,我想改到nebula, 去掉call{} 之后,最后的with 取出所有的return 值,重新组织排序的时候发现报错 [ERROR (-1004)]: SyntaxError: syntax error near WITH’`

我试了下nebula 支持with 的, 想请教下这个语句里面的with 逻辑改怎么改写?
BTW:因为有很多match 语句union 到一起,看了profile 好像 union 的各个语句不是并行的,所以想问问nebula 中有没有对这个并行优化策略?

在当前版本里,match 的 union 后没有办法做order by limit
考虑两种方式:

  1. 用 go 改写,go 支持;
  2. 不要用 union,用一个 match,把所有的边查出来,根据点/边类型做 case when 做过滤;
1 个赞
  1. 用go 的话改动太大了,语句二十几条
  2. 一个match 怎么写?现在用UNION 拼到一起的各个match 语句有不同的nodeType 和 orderWeight, 这个能改写吗?

感觉是可以的,用 case when?

MATCH p = (self:Company)<-[sr:Invest|Legal]-(target) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 RETURN target, p, 'C' AS nodeType, 1 AS orderWeight UNION MATCH p = (self:Company)<-[sr:FinalBenefit]-(target:Company) WHERE id(self)== -7835036839804393803 AND id(target)== -531217911035008506 AND sr.percent >= 5 RETURN target, p, 'BE5' AS nodeType, 5 AS orderWeight

这个两个的比较短,怎么改呀?

用go 改写发现也有问题,go 没办法保存路径,这样变量p 就没办法写了吧?

有没有其他同学帮忙看一下这个怎么改写合适?

这几天比较忙,没来得及看,我瞅瞅

大致写了下,供参考

(root@nebula) [basketballplayer]> match p=(self:player)-[sr]-(target) where id(self)=="player100" and id(target)=="player101" and ((type(sr)=="follow" and sr.degree > 90) or type(sr)=="serve") return target,p, case type(sr) when "follow" then 'C' when "serve" then 'BE5' end as nodeType, case type(sr) when "follow" then 1 when "serve" then 5 end as orderWeight
+-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+----------+-------------+
| target                                              | p                                                                                                                                  | nodeType | orderWeight |
+-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+----------+-------------+
| ("player101" :player{age: 36, name: "Tony Parker"}) | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})> | "C"      | 1           |
| ("player101" :player{age: 36, name: "Tony Parker"}) | <("player100" :player{age: 42, name: "Tim Duncan"})<-[:follow@0 {degree: 95}]-("player101" :player{age: 36, name: "Tony Parker"})> | "C"      | 1           |
+-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+----------+-------------+
Got 2 rows (time spent 11.519ms/13.225498ms)

谢谢。不过这个写法可能不太对吧,这个是要求查询的match 子句都是相同的跳数,但是当前业务里面实际上这个是不能不同的,比如:

{MATCH p = (self:Company)<-[sr:ACTUAL|CONTROL]-(target) WHERE self.keyNo = "236e31d3b25b16740e537cb4c153211a" AND target.keyNo = "7376bda598438361382715bf561c9c2f" RETURN target, p, 'C' AS nodeType, 1 AS orderWeight UNION MATCH p = (self:Company)<-[sr:ACTUAL|CONTROL]-()<-[:EMPLOY]-(target:Person) WHERE self.keyNo = "236e31d3b25b16740e537cb4c153211a" AND target.keyNo = "7376bda598438361382715bf561c9c2f" AND sr.percent >= 5 RETURN target, p, 'BE5' AS nodeType, 5 AS orderWeight} WITH target, p, nodeType, orderWeight RETURN target AS target, collect(p) AS path, collect(nodeType) AS nodeType, min(orderWeight) AS orderWeight, CASE target.status WHEN 'Yes' THEN 0 WHEN 'No' THEN 0 WHEN '' THEN 0 WHEN 'Yes_1' THEN 1 WHEN 'xx' THEN 1 WHEN 'xxx' THEN 10 WHEN 'xxxx' THEN 10 WHEN '***' THEN 11 WHEN '*' THEN 11 ELSE 8 END AS status ORDER BY status, orderWeight SKIP 0 LIMIT 100

@MuYi-方扬 这个有没有其他方式呀

(self:Company)<-[sr:ACTUAL|CONTROL*1…]-(target)
不固定条数的话,这里看改成 1…可以不可以。不过 type(edges)得用 reduce 处理下

这样改的好像太复杂了。
以后UNION 之后考虑增加 with … order by 语法吗

逻辑上段时间内不会了,因为会切到 GQL 里;
这个我想想能不能找人搞搞

GQL 这个会在什么版本时候推出呀?

em,社区版还要点时间

噢噢,了解了。这个语句还有没有什么好的改写办法呀。上面提到的(self:Company)<-[sr:ACTUAL|CONTROL*1…]-(target) 这个仔细思考了下,语意上表达完全不不同了,第一层的关系和第二层的关系是完全不同的。

现在最大的问题不是UNION 之后limit 而是想做group by, 原始neo4j使用collect 隐式去做的,nebula 目前这个能做吗? 没找到合适的方法?
尝试用nGQL 发现path 的语意无法表达出来

你起点终点都有,用 find path 呢

不太行,find path 不能在不同层级指定好对应的关系。
现在UNION 之后不能做任何操作吗? 重要的是UNION 之后 group by 这个语意