Създайте addEdge() Gremlin заявка, която няма да се дублира за 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', '#{id}').next(),
    g.V('id', '#{target.id}').next(),
    'follows',
    [since:#{Time.now.year}]
  ).unique(Direction.OUT)"

  $graph.execute(grem).results
end

В този документ има метод, наречен уникален, но изглежда не мога да го накарам да работи върху ръбове, само свойства на върхове.

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

Бих могъл да изпълня заявка преди create addEdge, за да проверя за съществуващ край, но това изглежда хакерско и може да причини проблеми с условие за състезание.

Възможно ли е да съществува метод, който мога да добавя към addEdge, който ще предотврати създаването на дублиращ се ръб, ако ръб вече съществува?

Или има ли начин да се създаде уникален етикет на свойство на ръб?

Ето сесия на гремлин по въпроса:

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, u2, '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, u, '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, u2, 'follows', [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, u2, 'follows', [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]

person brettu    schedule 12.09.2013    source източник


Отговори (2)


За да затворим цикъла тук, на този въпрос беше отговорено в Пощенския списък на Aurelius Graphs. По принцип:

ние наистина не виждаме случай на употреба за ограничения за уникалност, които да се прилагат към двойки върхове (a la - само един ръб може да съществува между връх A и B) поради следните причини:

  • повечето пъти можете да се отървете от дублирането доста евтино от страната на заявката с dedup(): v.out('follows').dedup().....
  • вероятността от конфликт е много по-ниска (поради N^2 комбинации от върхове), което прави заключванията просто много скъпи в сравнение с вероятността от конфликт.

Накратко, трябва да потвърдите съществуването на край във вашето приложение, тъй като то не може да бъде наложено от Titan.

person stephen mallette    schedule 16.09.2013
comment
Идемпотентните актуализации са неразделна част от разпределените системи. Декопирането работи... докато не модифицирате дадено предимство 1000 пъти (напр. промените теглото), след което започва масово изтичане на ресурси. - person Paul S; 25.10.2019

Това предотвратява дублирането в кода на приложението в сравнение с конфигурацията на DB и решава проблема, който имахме.

   grem = "
      if(g.V('uid', '#{id}').out('follows').has('id', g.V('uid', '#{target.id}').next().id).hasNext() == true){
        println 'already connected'
      } else{
        g.addEdge(
          g.V('uid', '#{id}').next(),
          g.V('uid', '#{target.id}').next(),
          'follows',
          [since:(new java.util.Date()).getTime()]
        )
      }"
    $graph.execute(grem).results
person brettu    schedule 16.09.2013