Может кто-нибудь объяснить, что делает этот обход графа в Гремлин? - PullRequest
0 голосов
/ 01 октября 2019

У меня возникли проблемы с пониманием этих запросов Gremlin:

from os import getenv
from gremlin_python.structure.graph import Graph
from gremlin_python.process.graph_traversal import __
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
 pmap = g.V().has(name, value) \
                .union(__.hasLabel('UID'), 
                       __.hasLabel('OID').outE('attached').inV()) \
                .union(__.propertyMap(),
                       __.inE('attached').outV().hasLabel('OID') \
                                         .propertyMap()).toList()

Итак, я понимаю g.V().has(name, value) is looking for a vertex with the key name = value . What is the union doing here? Is it unioning vertices with a label "OID" with edges that go outward with a label "attached"? What is the inV () `и почему два аргумента для объединения?

1 Ответ

1 голос
/ 01 октября 2019

Шаг union() просто объединяет дочерние потоки, предоставленные ему в качестве аргументов. Возьмите более простой пример:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('person','name','marko').union(has('age',29),bothE())
==>v[1]
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> g.V().has('person','name','marko').union(has('age',30),bothE())
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]

В первом примере мы получаем union(), в качестве начальной точки которого берется вершина "marko" для has('age',29) и bothE(). Поскольку v[1] также имеет свойство age со значением «29», мы видим v[1] в выводе. Мы также видим, что все ребра v[1] объединены в этот поток вывода. Во втором обходе мы видим, что v[1] отфильтровывается, поскольку «возраст» не равен «30», поэтому все, что мы получаем, это края.

Имея это в виду, подумайте, что делает обход, который вы включили в свой вопрос. Он находит вершину с «именем» и некоторым значением для этого ключа. Это становится отправной точкой для первого union(). Если вершина имеет метку «UID», то она проходит. Если вершина имеет метку «OID», то она пересекает исходящие «прикрепленные» ребра к смежной вершине и возвращает их.

Странно, что Vertex может иметь только одну метку(по крайней мере, по определению TinkerPop - некоторые графики поддерживают множественные метки элементов). Итак, предполагая один ярлык, вы действительно получаете только один или другой поток. Лично я не думаю, что использование union() - хороший выбор там. Я думаю, что было бы более интуитивно понятно использовать coalesce, так как можно вернуть только один поток, расширив мой пример сверху:

gremlin> g.V().has('person','name','marko').coalesce(has('age',30),has('age',29).bothE())
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> g.V().has('person','name','marko').coalesce(has('age',29),has('age',29).bothE())
==>v[1]

Использование coalesce() делает намерение намного более ясным, на мой взгляд. Далее с исходным кодом ко второму union() - в этот момент у вас либо есть исходные Vertex, либо одна или несколько «прикрепленных» вершин, для которых обход объединяет propertyMap() и / или propertyMap()из дополнительных «прикрепленных» вершин, имеющих метку «OID».

Трудно сказать точно, какова цель этого обхода с учетом предоставленной информации. Я полагаю, что в зависимости от структуры данных и намерений все может быть упрощено. Надеюсь, я, по крайней мере, объяснил, что делает union(), и пояснил, что для вас это, по-видимому, является основой вашего вопроса.

...