match/go 多Tag属性过滤

确实,这是我的低级错误,谢谢你这么及时的指正!我再继续验证多tag与多edge-type的属性过滤

大佬,您好!还有问题,请帮忙看下,谢谢!

  • 使用如下GQL能查询到一条路径
MATCH p=(v:player)-[e:follow|serve*1..2]->(v2)
where id(v) in ['player100'] and v2.player.name == 'Tony Parker'
RETURN nodes(p),relationships(p),length(p);
  • 为何使用下面的GQL却查询不到记录?我已经对follow,follow.degree创建了索引
MATCH p=(v:player)-[e:follow|serve*1..2]->(v2)
where id(v) in ['player100'] and v2.player.name == 'Tony Parker' and e.follow.degree >= 95
RETURN nodes(p),relationships(p),length(p);

这两个query不一样为啥结果要一样

我第二个查询的条件 e.follow.degree >= 95,在第一个查询结果中是满足的

e.follow.degree 写错了,建议有错先看文档,看看是不是语句写错了。

如果是边的 rank,应该使用 rank(e) 来引用。

参考文档中 where 子句使用 rank 作为过滤条件的部分:

如果是边的属性过滤,应该 e.degree,参考

1 个赞

除了边属性表达不写type之外,这里还有一个陷阱,当 e 是多条的时候 e 是一个 list:

如果想要通过描述多跳的边的过滤条件,比如-[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;

还有一种表达,用花括号,注意花括号要在星号之后:

(root@nebula) [basketballplayer]> match (n:player)-[e:follow{degree:95}*3]-(v) return n
[ERROR (-1004)]: SyntaxError: syntax error near `*3]-(v) '

Fri, 26 Nov 2021 17:11:34 CST

(root@nebula) [basketballplayer]> match (n:player)-[e:follow*3{degree:95}]-(v) return n
+-------------------------------------------------------+
| n                                                     |
+-------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"})    |
+-------------------------------------------------------+
| ("player125" :player{age: 41, name: "Manu Ginobili"}) |
+-------------------------------------------------------+

其实这个陷阱我有加到文档里,另外这也有收录

https://gist.github.com/wey-gu/f41e8a5651d95506b37bee6a8b5a1b8c

2 个赞

非常感谢大佬的指点!!在此基础上,我整理了一下如下实践,帮忙审核一下哈,谢谢!

  • Match查询子图实践,可以成功执行查询过滤
## 根据多edge-type进行1~2跳的子图查询
MATCH p=(v:player)-[e:follow|serve*1..2]->(v2)
## 指定起始顶点
where id(v) in ['player100'] 
## 过滤多tag属性
and (v2.player.name == 'Tony Parker' or v2.team.name == 'Warriors')
## 过滤多edge-type属性
and ALL(e_ in e WHERE (e_.degree >= 95 and type(e_) == 'follow') or (e_.start_year >= 2015 and type(e_) == 'serve')) 
## 过滤第几跳(e[0]表示第一跳)的多edge-type属性
and ((e[0].degree >= 95 and type(e[0]) == 'follow') or (e[1].start_year >= 2015 and type(e[1]) == 'serve'))
RETURN nodes(p),relationships(p),length(p),e,v,v2;
1 个赞

@wey 大佬,求助,下面的查询,我如何返回v2的指定属性?类似 v2.*.field1

MATCH (v:player)-[e:follow|serve*1..2]-(v2)
where id(v) == 'player100' and v2.player.name=='Tony Parker'
RETURN v,e,v2;
(root@nebula) [basketballplayer]> MATCH (v:player)-[e:follow|serve*1..2]-(v2) where id(v) == 'player100' and v2.player.name=='Tony Parker' RETURN v2.player.name;
+----------------+
| v2.player.name |
+----------------+
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
| "Tony Parker"  |
+----------------+

直接 v2.player.name 这样就可以的哈,是你想问的么?

主要是我的 v2中包含很多的tag,每个tag都有共同的属性id,name。
v2.tag1.id,v2.tag2.id…
我想返回v2所有tag的id和name,如:{id:v2..id, name:v2..name},类似这样的简写有吗?

明白了,我看你写的这个是 player 以为全是player 了,你只是举了一个例子。

return properties(v2).name 这样是可以的

对,我漏掉了这个函数,谢谢你!我尝试一下

只有模糊的情况才用它,知道类型的尽量写tag 哈

可以用 CASE WHEN 然后穷举 “player” IN labels(v2) 这样的

返回指定边的属性还是不会写,下面的报错了

MATCH (v:player)-[e:follow|serve*1..2]-(v2)
where id(v) == 'player100' and v2.player.name=='Tony Parker'
RETURN {id:id(v),name:v.player.name},{id:id(v2),name:properties(v2).name},ALL (e_ in e {start_year:properties(e_)});

RETURN [e_ in e | properties(e_).start_year]

1 个赞

谢谢大佬!我好好验证下

嗨,我在做属性过滤的时候,关于条件下推的,发现结果与预期的不一致,请帮忙解答一下,谢谢!

  • 查询nGQL
MATCH p=(v:player)<-[e:follow|serve*1..2]-(v2)
where id(v) == 'player100' and v2.player.name=='Tony Parker'
RETURN p,v,e,v2;
  • 查询结果,player125不满足条件为何能查出来,过滤的原理是啥?
  • 在变长路径中,边可以通过ALL(i in e where i.v < 1) 来过滤所有的边,但是在变长路径如何遍历指定过滤所有的点呢?

不要 return p

  • 去掉P,返回列中:v2 不包含 player125,但是在e列中包含
MATCH p=(v:player)<-[e:follow|serve*1..2]-(v2)
where id(v) == 'player100' and v2.player.name=='Tony Parker'
RETURN v,e,v2;