#gremlin #graph-traversal
#gremlin #обход графика
Вопрос:
При обходе графа я хочу рассматривать только ребра, которые имеют свойство, равное свойству одного из ребер, посещенных на предыдущем шаге обхода.
Я нашел http://tinkerpop.apache.org/docs/current/recipes/#traversal-induced-values но, похоже, это работает только для одного объекта, в моем случае мне нужно, чтобы значение менялось по мере прохождения. Например, начиная с V1, который имеет исходящие ребра (E1, E2, E3 …) Я хочу пройти от E1 до V2, а затем пройти вдоль любого ребра из V2, где edge.property (x) == E1.property (x), и сделать то же самое для всех ребер из V1 (E2, E3, …)
Я не могу найти никакой документации, которая поддерживает способ сделать это в Gremlin, возможно ли это?
Ответ №1:
Мы можем использовать современный игрушечный график, который поставляется с TinkerPop:
gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
Этот график уже содержит 6 ребер, из которых два имеют weight
из 1.0
:
gremlin> g.E().valueMap()
==>[weight:0.5]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:0.2]
Мы используем одно из этих двух ребер с weight
of 1.0
, чтобы получить другое ребро с таким же weight
значением. Проходя первое из этих двух ребер, мы приземляемся в вершине, которая имеет два исходящих ребра:
gremlin> g.V(1).outE().has('weight',1.0).inV().outE()
==>e[10][4-created->5]
==>e[11][4-created->3]
gremlin> g.V(1).outE().has('weight',1.0).inV().outE().valueMap()
==>[weight:1.0]
==>[weight:0.4]
Одно из этих ребер является другим с весом 1.0
. Итак, нам нужно отфильтровать эти ребра только на основе веса первого ребра:
gremlin> g.V(1).outE().has('weight',1.0).
as('firstEdge'). // save the first edge
inV().outE().
where(eq('firstEdge')). // compare with the first edge
by('weight') // use only the 'weight' property for the equality check
==>e[10][4-created->5]
Комментарии:
1. Есть ли какой-либо способ выполнить это без шага match ()? CosmosDB Microsoft Azure поддерживает язык запросов gremlin, ожидайте, что он пока не сможет обработать шаг match () : (
2. Спасибо, что спросили о
match()
шаге. Еще раз читая мой ответ, я заметил, что на самом деле здесь нет необходимости использоватьmatch()
. Я отредактировал свой ответ, чтобы решить проблему без использованияmatch()
, что, на мой взгляд, делает его намного более читаемым.3. как насчет фильтрации по
'secondEdge' - 'firstEdge' > 0.2
не просто эквалайзеру, а с помощью какой-нибудь простой арифметики?4. @jiamo: Это должно быть возможно с помощью
math()
шага . Пожалуйста, создайте новый вопрос, если вам нужна помощь с этим.