Как исключить вершины на основе ребер с помощью графа gremlin/IBM

Я работаю с графиком IBM и использую gremlin, чтобы попытаться отфильтровать определенные вершины. Мои края имеют две метки, обязательные и необязательные. эта ситуация:

   V3 -- V5 -- V6
  /  \
V1    \
  \    \
   V2 -- V4

Это немного похоже на цепочку спроса / предложения. V1 - это объект, который поставляет два типа расходных материалов (V3 и V2). Для работы V4 нужны оба источника. V5 нуждается в V3 и V6, чтобы иметь возможность работать. Так как у меня есть только V2 и V3. Мне нужен запрос, который позволяет мне перейти от V2 и V3 к каждой исходящей вершине, но исключить вершину, основываясь на том, есть ли у этой вершины ребро, которое требуется (но допускает необязательные ребра).

После долгих попыток вот что придумал коллега:

def g = graph.traversal(); g.V(1).out().outE().aggregate('edges').inV().where(inE('required').where(not(within('edges'))).count().is(eq(0))).dedup()

Это лучший способ сделать это? Или есть способ умнее?

1 ответ

Решение

Предполагая, что это ваш график:

gremlin> g.addV().property(id,1).as('1').
......1>   addV().property(id,2).as('2').
......2>   addV().property(id,3).as('3').
......3>   addV().property(id,4).as('4').
......4>   addV().property(id,5).as('5').
......5>   addV().property(id,6).as('6').
......6>   addE('supplies').from('1').to('2').
......7>   addE('supplies').from('1').to('3').
......8>   addE('required').from('2').to('4').
......9>   addE('required').from('3').to('4').
.....10>   addE('required').from('3').to('5').
.....11>   addE('required').from('6').to('5').iterate()

и это ожидаемый результат:

gremlin> g.V(1).
......1>   out().
......2>   outE().
......3>   aggregate('edges').
......4>   inV().
......5>   where(inE('required').
......6>         where(not(within('edges'))).
......7>         count().is(eq(0))).
......8>   dedup()  
==>v[4]

Тогда агрегирование ребер уже пройденных ребер, вероятно, является лучшим подходом. (В свои вопросы всегда лучше включать примерный график в виде скрипта Gremlin.) Полагаю, стоит отметить, что вам не нужны eq() в вашем is() а также not(without(...)) просто without:

gremlin> g.V(1).
......1>   out().
......2>   outE().
......3>   aggregate('edges').
......4>   inV().
......5>   where(inE('required').
......6>         where(without('edges')).
......7>         count().is(0)).
......8>   dedup() 
==>v[4]

Или просто покончите с подсчетом всех вместе, так как вы хотите, чтобы те вершины, которые не возвращали новые ребра, проходили

gremlin> g.V(1).
......1>   out().
......2>   outE().
......3>   aggregate('edges').
......4>   inV().
......5>   not(inE('required').
......6>       where(without('edges'))).
......7>   dedup()
==>v[4]

Приведенный выше подход может быть лучше, поскольку немедленный возврат только одного ребра из вашего фильтра inE('required').where(not(within('edges'))) немедленно отфильтрует вершину, и вам не нужно ждать подсчета всех ребер.

Другие вопросы по тегам