Сбор свойств и определенных типов узлов во время обхода графа Гремлина - PullRequest
1 голос
/ 11 мая 2019

У меня есть простой график типа:

(3) -> (2) -> (1)
 |     | |     |
(D)    |(B)   (A)
      (C)

В этом случае я хочу пройти от (3) до (1). Думайте об этом как о дереве, где узел (1) является корнем, а узел (3) является листом, а ребра между (3) - (2) и (2) - (1) представляют родительские отношения (2 является родителем 3 и т. д.).

В то же время каждая вершина, представляющая узел дерева (1, 2, 3), имеет один или несколько ребер, которые представляют отношения разрешений, поэтому в этом случае (A) представляет пользователя и отношение между (1) и (A) представляет разрешение (доступ), который пользователь (A) имеет (1). В случае (2) есть два пользователя, которые имеют доступ к этой вершине (B и C).

Вы можете себе представить, что узлы с номерами являются «папками» и имеют определенные атрибуты (например, имя), а узлы с буквами являются пользователями или разрешениями и тоже имеют определенные атрибуты (то есть имя, тип доступа и т. Д.).

Я могу успешно пересечь график от 3 до 1, печатая свойства каждого из узлов в пути (см. Пример ниже).

Так, например, если я сделаю:

gremlin> g.V('3').repeat(out()).until(has(id, '1')).path().by('name')
==>[folder1.1, folder1, root]

или

gremlin> g.V('3').repeat(out()).until(has(id, '1')).path().by('name')
==>[folder1.1, folder1, root]

gremlin> g.V('3').repeat(out('parent').simplePath().store('x')).until(has(id, '1')).cap('x')
==>{v[2]=1, v[1]=1}

// Although at this point I missed listing v[3]

Проблема в том, что мне нужно пройти по дереву и собрать разрешения таким образом, например (и формат может отличаться) Я ищу способ получить что-то в строках:

gremlin> ...
==>[ { { 3, name="foo" } , [ { D, permission="x" } ] }, { 2, [ {A, permission="y" }, {B, permission="z"} ] }, { { 3, name="foo" } , [ { D, permission="x" } ] } ]

В основном я хочу пройти путь от (3) до (1) (может быть больше трех узлов), собирая атрибуты вершины в пути и собирая вершины, связанные с определенными ребрами (только один уровень) Я не хочу расширяться за пределы одного края для разрешений) вместе с их атрибутами.

Обратите внимание, что я очень плохо знаком с гремлином, и я пытался и учился этому пару дней, даже не зная, возможно ли это ...

Любая идея, предложение будет оценено, спасибо!

1 Ответ

1 голос
/ 11 мая 2019

Когда вы делаете это:

gremlin> g.V('3').repeat(out()).until(has(id, '1')).path().by('name')
==>[folder1.1, folder1, root]

признает, что модулятор by() в path() является просто преобразованием.Модулятор применяется циклически к каждому элементу пути (поскольку вы указали только один by()).Это преобразование говорит: «возьмите элемент графа (то есть Vertex) в пути и извлеките значение свойства name и верните его, а не фактическую вершину».

Учитывая, что знания вам действительно нужныдругая форма преобразования, чтобы получить данные, которые вы хотите от пути.Обратите внимание, что by() имеет перегрузку, которая принимает Traversal в качестве аргумента, что означает, что вы можете применить Traversal к каждому элементу графа в пути.Я бы подумал, что project() будет хорошим шагом для получения желаемого результата - что-то вроде:

g.V('3').repeat(out()).until(has(id, '1')).
  path().
    by(project('name','permissions').
         by('name').
         by(out('permissions').fold()))

Обратите внимание, что в вышеприведенном сообщении сказано: "для каждой вершины в пути спроецируйте егона Map с ключами 'name' и 'permissions', где 'name' - это значение 'name' из вершины в пути, а 'permissions' - список связанных вершин разрешений. "

...