在计算多个号码共同联系人时,关于边方向的一些问题?

环境:
tigergraph : 2.6.0
os : centos release 6.5

之前在论坛问过,怎么计算多个号码的共同联系人.

后面在实践中发现,结果与实际不一致.漏掉了一些共同联系人。gsql语句如下:

create query com_contact(Set<vertex<phone>> phones) for graph mygraph{
    SumAccum<INT> @count;
    start = {phones};
    start =
      SELECT t //修改了一下这里
      FROM    start:s-(contact_phone:e)-contact:t
      ACCUM t.@count += 1
      HAVING t.@count >= 2
    ;
    PRINT start;
}

能过分析发现,分析出来的共同联系人.是在满足“start:s-(contact_phone:e)-contact:t”语句的s -> t 的条件下.而忽略了t -> s 的情况。受以前使用neo4j的影响,以为’-’ 表示的双向关系。

查询tigergraph官方资料。引用原话:
http://docs.tigergraph.com.cn/introduction-and-overview/gsql-101/built-in-select-queries#xuan-ze-bian
“注意,无论是无向边还是有向边,总是使用箭头->。这是因为我们描述的是查询在图中的遍历(搜索)方向,而不是边本身的方向”

在这里,我想确认一下。
如:“start:s-(contact_phone:e)-contact:t” 与“start:s-(contact_phone:e)->contact:t” 这两种执行结果是一样么。

如果,我想在满足条件 “s -> t”, "t -> s"这两种条件下的,共同联系人。我该怎么写呢?

说明。现在定义的边类型是有向型,默认不生成反向边(之前试过,有向型,默认生成么向边)

我在论坛上打到一些答案。v2语法支持我 反向边的查询问题。修改后的代码如下:

create query com_contact(Set<vertex<phone>> phones) for graph mygraph syntax v2{
    SumAccum<INT> @count;
    start = {phones};
    start =
      SELECT t 
      FROM    start:s-(<contact_phone:e)-contact:t
      ACCUM t.@count += 1
      HAVING t.@count >= 2
    ;
    PRINT start;
}

但问题来,查询速度变的太慢了,16s根本出不了结果,这是一个问题,第二个问题,我通过

修改timeout时间

gadmin --configure timeout

# 修改除GraphStudio.WebSocket.Timeout之外的timeout为3600(一小时)或者更长的时间

Test servers with supplied settings? [Y/n]

# 保存配置,输入y

Save settings? [y/N] y

gadmin config-apply

gadmin restart -fy

修改时间。没有生效。导致后在, 我出一直看不到结果。

这种场景建议使用无向边,因为contact_phone连接的两个顶点类型是不同的,所以不需要设为有向边即能指明方向。
如果使用有向边又不建反向边的话,反向查询性能必然不行。
关于TigerGraph中的数据建模一些建议,请在图课堂TIGERGRAPH图课堂观看“TIGERGRAPH图课堂之数据建模最佳实践”那一期,相信会对您有所帮助。

好的,不过我这实际情况是,只有一个类型的节点。(号码的类型),这样的情况,也不太适合建无向边吧!号码,有呼入,呼出的方向性。
我实际的发码是这样的。
create query com_contact(Set<vertex<phone>> phones) for graph mygraph{
SumAccum @count;
start = {phones};
start =
SELECT t //修改了一下这里
FROM start:s-(contact_phone:e)-phone:t
ACCUM t.@count += 1
HAVING t.@count >= 2
;
PRINT start;
}

TigerGraph的2个顶点之间是不存在多边的,而你2个电话之间是存在多次电话记录的。
所以可以2种建模的方式:

  1. 建立通话记录顶点,用通话记录分别连着呼叫方和被叫方电话;
  2. 直接用有向边连接两个电话,但对通话记录做些汇总,不记录每次通话记录,当然也可以考虑用一个list类型的属性记录通话记录。为了可以反查,可以给有向边加上反向边。

可以根据你最终要达到的业务目标选择不同的方案。

我看了你写的《图数据库建模最佳实践》修改了代码如下,达到了预期的目的。
create query com_contact(Set<vertex> phones) for graph mygraph{
SumAccum @count;
SumAccum @dst_phone;
start = {phones};
start =
SELECT t
FROM start:s-((contact_phone|reverse_contact):e)-phone:t
ACCUM t.@dst_phone += s. number
HAVING t.@dst_phone.size()>= 2
;
PRINT start.number;
}
不过看了你的回复,反到有疑问了,为什么两个顶点之间不能有多个边。比如。号码A,B A给B打过电话。B也给A打过电话。我选择有向型,自动加反向边建模。这个时候,不是有4条边?

接着反向边的问题,我想继续请教一下林老师。tigergraph是出于什么的考虑,进行这样的设计,仅仅是方便反向访问?

这是由TigerGraph的边的特质决定的,边的主键可以理解成起点的主键+终点的主键,所以两个点之间的同一类型的边只能有一条。如果用一条有向边从电话A指向电话B,那么这条边上只能记录由A打给B的所有通话记录的一些汇总信息。
您说的4条边是没错的,A->B有一条有向边、一条反向边;B->A也有一条有向边、一条反向边。
我说的指的是,A->B打了N通电话,想有得到N条有向边,这是TigerGraph不支持的,要想实现这功能,只能另外加类顶点“通话记录”,分别连接着呼叫者和被叫者。

有些场景会用到有向边+反向边,比如“公司”之间的“控股”关系,有的时候要从母公司出发,查子公司,这时就要从母公司通过有向边“控股”找到子公司;有的时候要从子公司出发,查母公司,这里就要从子公司通过反向边“被控股”找到母公司。

“两个点之间的同一类型的边只能有一条”,改为"两个点之间的同一类型且同方向的边只能有一条"。是不是更准确一些?至少不同方向,相同类型的边,我是可以创建方向相反的两条边。对于A给B打了多次电话,只有一条边,这个我理解,再这点上,好像,tigergraph在我多次创建A->B的关系时,只给我创建一条边,这相当于给我做了去重的功能,也相当于mysql的唯一索性,蛮好的。

对的,这个说法比较准确。

是的,这个了解过,这其实就是我说的,方便反向访问的目的把。谢谢林老师。想顺便说一下,我接触了,tigergraph一段时间。有几点感触,1)在数据导入方面,你们做的体验是最好的,之前,我接触过,neo4j,hugegraph,orientdb。你们通过你们的graphstudio就能进行大量的数据导入。体验很好,真个导入过程的交互设计也很棒。2)累加器的设计,在一些场景中,可以很优雅的使用gsql去实现。
不足的是,1)好像在国内的知名度,不是特别大。不过我发现,你们应该还在百度上买了排名打广告的。我有这个印象,不过,我第一次在百度搜图数据库,你们出现在第一页时,我想,这图数据库肯定不行,居然还在百度打广告,公司可能有点钱。^-^。2)没有一个,tigergraph用户,畅通的交流渠道,看我现在跟您在这里交流,都是用手机移动的网络。很不方便。
总的来说,感觉得出来,tigergraph是一个用心设计,不错的图数据库。后面我会继续深入了解,tigergraph。希望到时候林老师还要多多指教啊!

感谢您的支持和建议!
数据导入虽然用UI也可以用,不过这能支持的数据量级很有限,最多只能支持500M的数据。
所以我们一般客户都是在后台用gsql命令执行gsql文件导的数,如果未来您的数据量加大的话,还是建议用这种方式。