Как исключить вершины на основе ребер с помощью графа 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')))
немедленно отфильтрует вершину, и вам не нужно ждать подсчета всех ребер.