请教一下,在match语句里可以访问同一个vertex的不同tag的属性吗?我看文档里貌似是不可以的。
类似下面这样吗?
(root@nebula) [nba]> desc tag player
+--------+----------+-------+---------+
| Field | Type | Null | Default |
+--------+----------+-------+---------+
| "name" | "string" | "YES" | |
+--------+----------+-------+---------+
| "age" | "int64" | "YES" | |
+--------+----------+-------+---------+
Got 2 rows (time spent 1317/1732 us)
Wed, 20 Jan 2021 17:01:18 CST
(root@nebula) [nba]> desc tag bachelor
+--------------+----------+-------+---------+
| Field | Type | Null | Default |
+--------------+----------+-------+---------+
| "name" | "string" | "YES" | |
+--------------+----------+-------+---------+
| "speciality" | "string" | "YES" | |
+--------------+----------+-------+---------+
Got 2 rows (time spent 1533/1984 us)
Wed, 20 Jan 2021 17:01:23 CST
(root@nebula) [nba]> match (v:player{name: "Tim Duncan"}) RETURN v.age, v.speciality, labels(v) as labels
+-------+--------------+------------------------+
| v.age | v.speciality | labels |
+-------+--------------+------------------------+
| 42 | "psychology" | ["bachelor", "player"] |
+-------+--------------+------------------------+
Got 1 rows (time spent 6767/7186 us)
Wed, 20 Jan 2021 17:01:26 CST
player和bachelor两个tag都有name属性,return v.name的时候我试了好像只会返回其中一个tag的name属性,而通过GO语句是可以指定哪个tag的name属性的
这里是为了跟 openCyher 保持兼容,才做成这样的。其实客户端是把所有的 tag 的属性都返回了,如果你要在客户端使用,可以直接拿点,然后自己去拿哪个 tag 的哪个属性都是可以的:
(root@nebula) [nba]> match (v:player{name: "Tim Duncan"}) RETURN v
+-------------------------------------------------------------------------------------------------------------+
| v |
+-------------------------------------------------------------------------------------------------------------+
| ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) |
+-------------------------------------------------------------------------------------------------------------+
Got 1 rows (time spent 7388/7821 us)
Wed, 20 Jan 2021 17:15:05 CST
在where条件里有办法基于player的name进行过滤吗?
就这个 case 而言,已经使用了 player.name
进行的过滤,为什么还要在 WHERE
中再加过滤呢?能否写一下你的使用用例?
是这样,我是希望通过vid的方式选定起始点,假设通过follow关系跳转到v2,v2也是具有player和bachelor两个tag,这时我想通过player的name属性对v2进行过滤,这个有办法实现吗?
如果像示例中的 player 和 bachelor 一样,有相同的 tag 属性,match 中是不好区分哪个 tag 的。这个如果又是必须的话,可以使用 GO 来实现。
预格式化文本将缩进 4 格
match (v)-[:follow]->(v2) where id(v) == 'player102' and v2.name== 'Tony Parker' return v2;
[ERROR (-8)]: Can't solve the start vids from the sentence: MATCH (v)-[:follow]->(v2) WHERE ((id(v)==player102) AND (v2.name==Tony Parker)) RETURN v2
还有个问题麻烦也看下,按照我刚才说的case,报这个错,但是我对v2的条件应该跟起始vid无关吧?
你好,这里是 MATCH
的实现的问题,现在索引提取还有一些工作正在做,目前的 case 可以通过如下的方式来规避一下:
(root@nebula) [nba]> match p=(v)-[:like]-(v2 {name: "Tony Parker"}) where id(v) == "Tim Duncan" return v2, p
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| v2 | p |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 95}]-("Tony Parker" :player{age: 36, name: "Tony Parker"})> |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Got 2 rows (time spent 8845/9414 us)
Thu, 21 Jan 2021 10:01:20 CST
版本:Nebula Graph 2.0.0-rc1
使用 match ,利用 where 对 vertex and edge 做条件过滤时,遇到类似的问题
对 source vertex 的 id 和 edge 的一个 timestamp 属性 exec_time
做过滤,报错 Can't solve the start vids from the sentence
如果去掉 edge exec_time
的过滤条件,可以正常查询。
请问如何利用 where 进行查询?或者按照 @yee 大佬给出的方式,在 edge 的属性中过滤,{} 里如何写 “大于等于某个数值” 的条件?
问一下,match这块后续有考虑兼容多Tag的情况吗?譬如通过函数扩展一下。
以之前的player和bachelor两个tag都有name属性为例,在过滤时可以通过类似:getProperty(v2, bachelor, name) == ‘Tim Duncan’,第二个参数指定了Tag
Good point!
nebula 的目标是最大可能的兼容 openCypher 中的 MATCH 功能,像你说的多 TAG 的情况,如果 openCypher 中可以,nebula 将来也会努力去支持,目前的 MATCH 的功能还只是一小步,其中的功能点有很多,需要一定的时间来完善,但是从实现的角度来讲是没有问题。
我从 openCypher 的文档中没有看到 getProperty
的函数,上面的表达式或许可以通过类似的方式来表达:
MATCH (v2:bachelor{name: "Tim Duncan"}:player)
不过这种是表达 equal 的形式,如果是不等可能需要考虑你的建议方式。 @steam 这个问题可以记录一下,看看是否有好的方式或者变为需求。
版本:Nebula Graph 2.0.0-GA
尝试用 GA 版本去做上述多属性的查询,比如:
match (src) -[e:data_flow]- (dst) where id(src)=="src_vertex_id" and e.exec_time>=1616601600 return src, e, dst
可以查询成功,GREAT !
但如果是查询多跳,如下则无返回(连上述第一跳的结果都没有了):
match (src) -[e:data_flow*1..2]- (dst) where id(src)=="src_vertex_id" and e.exec_time>=1616601600 return src, e, dst
用 GO 语句是能够查询到相应的上下游多跳。
先说下我本地验证的结论:
(user@nebula) [nba]> match (v)-[e:like]-(v2) where id(v)=="Tim Duncan" and e.likeness>90 return v2
[ERROR (-8)]: Can't solve the start vids from the sentence: MATCH (v)-[e:like]-(v2) WHERE ((id(v)=="Tim Duncan") AND (e.likeness>90)) RETURN v2
Sun, 28 Mar 2021 23:51:30 CST
(user@nebula) [nba]> match (v)-[e:like*1..2]-(v2) where id(v)=="Tim Duncan" and e.likeness>90 return v2
[ERROR (-8)]: Can't solve the start vids from the sentence: MATCH (v)-[e:like*..2]-(v2) WHERE ((id(v)=="Tim Duncan") AND (e.likeness>90)) RETURN v2
Sun, 28 Mar 2021 23:51:40 CST
(user@nebula) [nba]> match (v:player)-[e:like]-(v2) where id(v)=="Tim Duncan" and e.likeness>90 return v2
+---------------------------------------------------------------+
| v2 |
+---------------------------------------------------------------+
| ("Dejounte Murray" :player{age: 29, name: "Dejounte Murray"}) |
+---------------------------------------------------------------+
| ("Tony Parker" :player{age: 36, name: "Tony Parker"}) |
+---------------------------------------------------------------+
| ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) |
+---------------------------------------------------------------+
| ("Tony Parker" :player{age: 36, name: "Tony Parker"}) |
+---------------------------------------------------------------+
Got 4 rows (time spent 68064/68469 us)
Sun, 28 Mar 2021 23:51:52 CST
(user@nebula) [nba]> match (v:player)-[e:like*1..2]-(v2) where id(v)=="Tim Duncan" and e.likeness>90 return v2
Empty set (time spent 476908/477156 us)
Sun, 28 Mar 2021 23:52:02 CST
明天我到公司看下这里的实现问题,有结论了再回复你。
抱歉,今天才有时间帮你看这个问题,针对变长的 MATCH 第二种写法是有问题的,因为是变长这时的 e
表示的其实是个边的 list
,所以这里变长的正确写法应该是:
match (src) -[e:data_flow*1..2]- (dst)
where id(src)=="src_vertex_id" and e[0].exec_time>=1616601600
return src, e, dst
表示的是对第一度的边过滤
如何对所有的 e 进行过滤呢?
可以试试 all 函数:
match (src) -[e:data_flow*1..2]- (dst)
where id(src)=="src_vertex_id" and all(t IN e WHERE t.exec_time>=1616601600)
return src, e, dst