2013-09-12 3 views
4

Есть ли способ создать уникальное ребро между двумя вершинами на графике Titan и подтвердить, что он не может быть создан снова, если только он не удален и не воссоздан?Создайте запрос 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

Я мог бы выполнить запрос перед создать addEdge для проверки существующего края, но это кажется Hacky и может вызвать проблемы с состоянием гонки.

Возможно ли существовать метод, который я могу добавить в 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 | ОБА | 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] 

ответ

6

Чтобы закрыть петлю здесь, этот вопрос был дан в Aurelius Graphs Mailing List. В основном:

мы действительно не видим случай использования для ограничения уникальности применить к парам вершин (а-ля - только один край может существовать между вершиной А и В) по следующим причинам:

  • в большинстве случаев, вы можете избавиться от дублирования довольно дешево на стороне запроса с DeDup(): V.OUT («следует») DeDup() .....
  • вероятность конфликта. намного меньше (из-за комбинаций N^2 вершин), что делает блокировки просто waaaay до дорогостоящего по сравнению с вероятностью конфликта.

Короче говоря, вы должны проверить наличие края в вашем приложении, поскольку он не может быть обеспечено с помощью Titan.

0

Это предотвращает дублирование кода приложения в сравнении с конфигурацией БД и решает проблему, которую мы имеем.

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 
Смежные вопросы