根据边的属性匹配

  • nebula 版本:2.6.0
  • 部署方式:分布式
  • 安装方式:Docker
  • 是否为线上版本:N
  • 硬件信息
    • 磁盘( 推荐使用 SSD)
    • CPU、内存信息
  • 问题的具体描述

你好,我想根据边的属性来筛选出所有的node,
MATCH (v)-[e*1…2]-(v2) WHERE e.name in [“功效”] RETURN v; LOOKUP也使用了,也不行,请问有什么方法能有效率地实现呢?

MATCH 的使用前提是创建了索引,你创建了 name 这个边索引吗?

这里有一个陷阱,多条边时候 e 是 array/list,不能用 e.name 的语义

参考 MATCH - Nebula Graph Database 手册 中的注意

如果想要通过描述多跳的边的过滤条件,比如-[e:follow*2]->,这时候 e 不再是单条边时候的数据类型了,而是一列边组成的列表,例如: 以下语句可以运行但是没有返回数据,因为e是一个列表,没有.degree的属性。

nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
        WHERE e.degree > 1 \
        RETURN DISTINCT v2 AS Friends;

这是正确的表达:

nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
        WHERE ALL(e_ in e WHERE e_.degree > 0) \
        RETURN DISTINCT v2 AS Friends;

进一步,这是表达对多跳边的第一跳的边属性过滤的表达:

nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
        WHERE e[0].degree > 98 \
        RETURN DISTINCT v2 AS Friends;
1 个赞


是创建了的,并且也是在创建索引之后再导入的数据。单独去查edge的时候是可以的。


也是不行的

如果指定了头节点的tag,又可以出来结果,但是效率很低,如图:

如果只指定边类型呢?...[e:edgeType*2]...,边的 name 条件都指定的话,应该可以限定边类型吧?这样扫索引应该会快很多

这样是可以的。但是这样的话我就要事先列出所有的边是吗?,不指定的话不能默认取所有的边吗?

不是所有的边都有 .name 的索引/ 或者不是同一个索引,所以就不能利用索引去扫,优化规则就不能去只扫这个传统中医治疗的边索引。这个信息提供出来相当于告诉了 nebula 去扫这个 edge type 的索引。

明白你的意思了

你好,指定多个edges的时候又不行了。。。。

多了一个冒号


文档里面不是说可省略也可不省略吗?跟这个没关系,我省略了之后还是同样的错误

嗯嗯,对,都支持,这里应该是不支持多边索引的表达,这是因为点边索引现在不能跨类型,所以做不到组合的情况,可以利用并集把两个 MATCH 结合,但是就只有纯的一种边多跳的结果能满足你的需求么?

:joy:如果想实现我的需求的话,有多少个edges,我就得执行这个语句多少次是吧? 没有其他的方法了吗?

最后一句字都看得懂,合在一起就不懂了。只有纯的一种边多跳的结果能满足我的需求,不是很理解你的意思

可以在一个 query 里,用 UNION 连接两个,但是注意这样不包含 v-[edgeA]-[edgeB]-v1 这种组合的情况了。

MATCH p=(v)-[e:serve*2]->(v2) WHERE ALL(e_ in e WHERE e_.degree > 0) RETURN DISTINCT v2 \
  UNION \
MATCH p=(v)-[e:follow*2]->(v2) WHERE ALL(e_ in e WHERE e_.degree > 0) RETURN DISTINCT v2

另外的方式就是指定一下 v:的 tag,应该也可以,如果能推得的信息尽量填到 query 里,这种是从 tag 开始扫,没有剪枝条件,会比较慢,但是包涵交叉 edge 的情况

(root@nebula) [basketballplayer]> MATCH p=(v)-[e:follow|serve*2]->(v2) WHERE ALL(e_ in e WHERE e_.degree > 0) RETURN DISTINCT v2;
[ERROR (-1009)]: SemanticError: Can't solve the start vids from the sentence: MATCH p = (v)-[e:follow|serve*2]->(v2) WHERE all(__VAR_0 IN e WHERE ($__VAR_0.degree>0)) RETURN DISTINCT v2

Tue, 14 Dec 2021 15:01:35 CST

(root@nebula) [basketballplayer]> MATCH p=(v:player)-[e:follow|serve*2]->(v2) WHERE ALL(e_ in e WHERE e_.degree > 0) RETURN DISTINCT v2;
+------------------------------------------------------------+
| v2                                                         |
+------------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"})         |
+------------------------------------------------------------+


emmm…多个的话不可以

试试这么写呢?先 UNION 多个边索引的 LOOKUP,再管道之后从起点 GO n STEPs,然后再在 WHERE 里 OR 每一种边的条件。

(LOOKUP ON serve WHERE serve.start_year > 1000 UNION LOOKUP ON follow WHERE follow.degree > 20) \
| GO 2 steps FROM $-.SrcVID OVER serve, follow WHERE serve.start_year > 1000 or follow.degree > 20

但是我有10多条边,我要写10多个union吗? :hot_face: