go语句查询结果问题

提问参考模版:

  • nebula 版本:2.6.1
  • 部署方式:分布式
  • 安装方式:RPM
  • 是否为线上版本:Y
  • 硬件信息:NVME 480G, CPU 16C MEM 77G
  • 问题的具体描述
    大家好,我们使用nebula存储用户关系数据,每个vertex绑定唯一的tag,使用tag类型表示vertex关系类型,在使用go语句查询时,有一个查询功能,与预期的查询结果不符,因是初次使用可能理解不到位,特来请教。

场景: 查询某个vertex在1-4个步长内,匹配vertex vid以某个字符串开头,返回这个vertex的vid,及其tag属性信息

查询语句:go 1 to 4 steps from “uid_7D475C1F26E31A211FC7722C550BC035” over * BIDIRECT where dst(edge) starts with “guid_” yield distinct dst(edge) as vid, properties($$).id as id, properties($$).createAt as createAt;

查询结果:


第一条结果为目标结果,我理解的应该只返回这一条信息即可
第二条数据vid与第一条相同,但是vertex tag属性id不是当前vertex的id,而是目标点的前置vertex,如下图

图:

帮忙看下是否语句有问题,还是有其他的问题导致,特此感谢

首先dst(edge)跟edge._dst是不一样的,所以需要根据需求选择用哪种方式,我这面弄了一个1跳的对比你可以看看

首先感谢回复,从你的图中我理解了下,src(edge)和dst(edge)返回的是edge的起点和终点,而edge._src、 edge._dst、 $^ 、 $$ 是path的起终点呢

例如我截图中的例子,edge._src、 edge._dst、 $^ 、 $$这种情况的起点是go from的这个点

嗯,这些的区别我大概已经理解, 但是如下图,第二行的记录,我还是有些疑惑,因为where条件做了限制终点是guid_开头的vid的点,为何会出现 id($$)返回 uid_开头的点呢 (见红框处),感谢回复

会不会有其他的边类型从id5719083指向了idzx4439282000?
这个语句一个是over *,另一个是bidirect(双向),这些都有可能存在问题。
建议:go 1 to 4 steps from “uid_7D475C1F26E31A211FC7722C550BC035” over browseRelated BIDIRECT where browseRelated.dst starts with “guid” yield distinct browseRelated._dst as vid, $$.<tag名称>.id as id, $$.<tag名称>.createAt as createAt;
试试看结果

首先,从id5719083到idzx4439282000在我当前的示例中只有唯一的边类型,其次,你建议的语句,我这边目前使用不了,因为我这边二个点之间的边类型存在多个,无法确实是哪种; 其实我的疑惑点在于where条件dst(edge) starts with "guid_"到底筛选的是什么? 是说go语句匹配的路径的终点的vid要以guid_开头,还是说go语句匹配的路径中存在以guid_开头的点即可,如果是第一种情况,那$$不应该出现uid_的情况,感谢解惑

where条件dst(edge) starts with "guid_"到底筛选的是什么?
是go语句匹配的路径的终点的vid要以guid_开头。
以你的语句为例,go 1 to 4 steps,首先1跳,拿到边的dst.vid,再根据guid做筛选保留结果集,再做2跳,拿到边的dst.vid,继续删选保留结果集,以此类推到4跳,最终结果是这4个结果集的合集

明白了, 那是不是不应该出现id($$)以uid_开头的情况呢

语句的过滤条件是dst(edge) starts with “guid_”,这个过滤是针对于边的。
id($$)这个是点的,参考我最开始截图的例子。
1.go 1 to 4 steps from “uid_7D475C1F26E31A211FC7722C550BC035” over * BIDIRECT where dst(edge) starts with “guid_”
这一步就是对边做了一定的筛选

2.yield distinct dst(edge) as vid, properties($$).id as id, properties($$).createAt as createAt;
这一步就是我想要的输出结果,dst(edge) as vid因为前面的筛选,所以输出是正常的,properties($$).id as id, properties($$).createAt as createAt;输出边连接的点的信息,我觉得这块是你疑惑最大的地方,从咱俩交流来看,我感觉这两个id之间是有两条边的,一个A->B,一个B->A

明白你的意思了,最后的疑问,我可以给你答案,不存在二条边

嗯,那可能是BIDIRECT的问题,可以去掉试试,然后再换成REVERSELY试试,对比一下结果

如你所说,我尝试了一下,正向和反向的查询,结果都是没查到结果;
正向:


反向:

如一开始的图探索所示,这里只能使用BIDIRECT查能查询到

嗯,你说的对,1 to 4 step这个从图上看确实只有双向才能出结果,我这面做了一个图


从A出发双向一跳 A->B A->C
继续二跳 B<-A B<-C B<-D C<-A C->B C<-D
后面三跳四跳都是以此类推
通过过滤条件,我们得到的最终结果是 D->E和E<-D这两种情况
dst(edge)这个前面说过,必然是E的vid
properties($$).id得到的却是点E和D的id,所以会出现有两条记录

因为 dst(edge) starts with “guid_” 并没有对 id($$) 做前缀过滤,改成 id($$) starts with "guid_"

2 个赞

这个不是对边的实际终点做过滤吗?

嗯,我意思就是边的终点,而不是语句的查询出来的终点,比如D->E和E<-D,过滤的都是E,而不是E和D

过滤的是 E,那么 id($$) as vid2 也就是 D,vid2 出来 uid_ 开头的点不是很正常吗?

感谢二位,已经比较清晰了