加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 创建一个不会重复Titan的addEdge()Gremlin查询

发布时间:2020-12-17 03:31:38 所属栏目:百科 来源:网络整理
导读:有没有办法在Titan图上的两个顶点之间创建一个唯一的边,并确认无法再次创建它,除非删除并重新创建? 基本上我需要创建: vertex1--follows--vertex2 但我继续为同一个关系创建多个边: vertex1--follows--vertex2vertex1--follows--vertex2vertex1--follows-
有没有办法在Titan图上的两个顶点之间创建一个唯一的边,并确认无法再次创建它,除非删除并重新创建?

基本上我需要创建:

vertex1--follows-->vertex2

但我继续为同一个关系创建多个边:

vertex1--follows-->vertex2
vertex1--follows-->vertex2
vertex1--follows-->vertex2
vertex1--follows-->vertex2

我的基本addEdge查询是这样的:

def follow(target)
  grem = "g.addEdge(
    g.V('id','#{id}').next(),g.V('id','#{target.id}').next(),'follows',[since:#{Time.now.year}]
  )"

  $graph.execute(grem).results
end

我想要找到的是这样的

def follow(target)
  grem = "g.addEdge(
    g.V('id',[since:#{Time.now.year}]
  ).unique(Direction.OUT)"

  $graph.execute(grem).results
end

在这个文档中有一个名为unique的方法,但我似乎无法在边缘上工作,只能在顶点属性上工作.

https://github.com/thinkaurelius/titan/wiki/Type-Definition-Overview

我可以在创建addEdge之前运行查询以检查现有边缘,但这看起来很麻烦并且可能导致竞争条件问题.

是否有可能存在一个方法,我可以附加到addEdge,如果边缘已存在,将阻止创建重复边缘?

或者,有没有办法在边缘创建一个独特的属性标签?

这是问题的一个gremlin会话:

gremlin>  g.makeType().name('follows').unique(IN).makeEdgeLabel();
==>v[36028797018964558]
gremlin> u = g.addVertex([name:'brett'])
==>v[120004]
gremlin> u2 = g.addVertex([name:'brettU'])
==>v[120008]
gremlin> e = g.addEdge(u,u2,'follows')
==>e[2w5N-vdy-2F0LaTPQK2][120004-follows->120008]
gremlin> e = g.addEdge(u,'follows')
An edge with the given type already exists on the in-vertex
Display stack trace? [yN] 
gremlin> e = g.addEdge(u2,u,'follows')
==>e[2w5P-vdC-2F0LaTPQK2][120008-follows->120004]
gremlin> u3 = g.addVertex([name:'brett3'])
==>v[120012]
gremlin> e = g.addEdge(u3,'follows')
An edge with the given type already exists on the in-vertex
Display stack trace? [yN] N
gremlin> g.E
==>e[2w5N-vdy-2F0LaTPQK2][120004-follows->120008]
==>e[2w5P-vdC-2F0LaTPQK2][120008-follows->120004]

设置唯一(IN | BOTH | OUT)会产生一个问题,即每个用户只能有一个关注者.这当然会使用户无法使用 – >跟随 – > [用户]关系.

这是尝试在边缘上设置唯一属性的另一个示例,这也失败了:

gremlin> g.makeType().name('follows_id').unique(BOTH).makeEdgeLabel();
==>v[36028797018964942]
gremlin>  u = g.addVertex([name:'brett'])
==>v[200004]
gremlin>  u2 = g.addVertex([name:'brett2'])
==>v[200008]
gremlin>  u3 = g.addVertex([name:'brett3'])
==>v[200012]
gremlin> e = g.addEdge(u,[follows_id:'200004-20008'])
Value must be a vertex
Display stack trace? [yN] N
gremlin> g.E
==>e[4c9z-Q1S-2F0LaTPQQu][200004-follows->200008]
gremlin> e = g.addEdge(u,[follows_id:'200004-20008'])
Value must be a vertex
Display stack trace? [yN] N
gremlin> g.E
==>e[4c9z-Q1S-2F0LaTPQQu][200004-follows->200008]
==>e[4c9B-Q1S-2F0LaTPQQu][200004-follows->200008]

解决方法

要在这里关闭循环,这个问题在 Aurelius Graphs Mailing List中得到了解答.基本上:

we don’t really see a use case for a uniqueness constraints to apply
to pairs of vertices (a la – only one edge can exist between vertex A
and B) for these reasons:

  • most times,you can get rid of the duplication quite cheaply on the query side with a dedup(): v.out(‘follows’).dedup()…..
  • the likelihood of conflict is much lower (due to the N^2 combinations of vertices) which makes locks just waaaay to expensive
    compared to the likelihood of conflict.

简而言之,您应该在应用程序中验证边缘存在,因为Titan无法强制执行.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读