Отобразить тип обхода Гремлин (Edge, Vertex, Property) в шаге CHOOSE, возможно? - PullRequest
1 голос
/ 05 февраля 2020

Я расширяю код sparql-to-gremlin для поддержки полностью и частично несвязанных запросов предикатов, которые могут использоваться автоматизированными процессами для изучения структуры графа. Идея в том, что вы можете просто подключиться к некоторой графовой БД и задать полностью несвязанный запрос с некоторым лимитом и получить свойства вершин, типы ребер, свойства ребер и т. Д. c. Затем это можно изучить подробнее.

Теперь я могу решить полностью несвязанный запрос и решить тот, у которого субъект связан с вершиной. Теперь я пытаюсь объединить его в мультитеральный запрос и обнаружил, что шаг Gremlin MATCH должен отражать тип обхода, прежде чем он сможет решить, какие шаги действительно будут применяться. Например, если Обход приводит к Вершине, имеет смысл запросить / в ребрах и свойствах; однако, если это Edge, запрос на вывод / в ребра не имеет смысла и на самом деле приводит к ошибкам при выдаче неожиданного типа.

Таким образом, вопрос, можно ли написать своего рода оператор «switch», который будет размышлять о типе, а затем только спрашивать о вещах, которые имеют смысл в этом контексте?

Вот один из типов запросов SPARQL, которые я пытаюсь поддержать (на основе описанного здесь Графа Богов https://old-docs.janusgraph.org/0.1.0/getting-started.html):

https://old-docs.janusgraph.org/0.1.0/images/graph-of-the-gods-2.png

SELECT ?BATTLE ?PRED ?VALUE
WHERE {
    vid:6 ep:battled ?BATTLE .
    ?BATTLE ?PRED ?VALUE .
}

Здесь мы начинаем с вершины с идентификатором 6, захватывая ссылку на исходящий край с помощью «сражен» ”, Затем захватывая все возможные свойства ребра вместе с их значениями.

Здесь вершина с id 6 - это Геркулес, у которого есть 3 исходящих ребра с меткой« сраженный », идущих в вершину с идентификатором 9 (Nemean), 10 (Гидра) и 11 (Цербер). Я хотел бы, чтобы? PRED был привязан к v: id (идентификатор края), v: метка (метка края), v: время (значение свойства времени края), v: место (значение свойства края края), eps: сраженный (расширение sparql-to-gremlin, связывающего ребро с вершиной IN).

1 Ответ

0 голосов
/ 06 февраля 2020

Я думаю, что следую за вашей проблемой, и я не думаю, что у меня есть хороший ответ для вас. На данный момент Gremlin не очень хорош в обнаружении типов, и проблема остается открытой на TINKERPOP-2234 . Типичный обходной путь для большинства людей, когда они имеют смешанный набор элементов в потоке, состоит в том, чтобы использовать шаг, подобный coalesce() или choose(), чтобы действовать как форму оператора switch, а затем найти некоторый фильтр, который может идентифицировать тип объекта. Итак, вот несколько смешанных результатов, которые я придумал:

gremlin> g.V().union(outE(),__.in())
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
==>v[1]
==>v[1]
==>v[4]
==>v[6]
==>e[10][4-created->5]
==>e[11][4-created->3]
==>v[1]
==>v[4]
==>e[12][6-created->3]

, а затем я проверяю с помощью hasLabel() для меток, которые, как я знаю, принадлежат только вершинам, тогда все остальное должно быть ребром:

gremlin> g.V().union(outE(),__.in()).choose(hasLabel('person','software'), values('name'), values('weight'))
==>0.4
==>0.5
==>1.0
==>marko
==>marko
==>josh
==>peter
==>1.0
==>0.4
==>marko
==>josh
==>0.2

Не идеально, очевидно, но обычно он решает проблемы большинства людей. Надеемся, что мы увидим решение TINKERPOP-2234 для 3.5.0.

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

gremlin> g.V().union(outE(),__.in()).choose(filter{it.get() instanceof Vertex}, values('name'), values('weight'))
==>0.4
==>0.5
==>1.0
==>marko
==>marko
==>josh
==>peter
==>1.0
==>0.4
==>marko
==>josh
==>0.2
...