Как использовать несколько шагов объединения в запросе gremlin?

#cypher #gremlin #gremlinpython

Вопрос:

Я хочу преобразовать следующий запрос cypher в gremlin, но столкнулся с проблемой при использовании union.

 match d=(s:Group{id:123})lt;-[r:Member_Of*]-(p:Person) with d, RELATIONSHIPS(d) as rels WHERE NONE(rel in rels WHERE EXISTS(rel.`Ceased On`)) return *  UNION  match d=(s:Group{id:123})lt;-[r:Member_Of*]-(p:Group)-[r1: Member_Of*]-gt;(c:Group) with d, RELATIONSHIPS(d) as rels WHERE NONE(rel in rels WHERE EXISTS(rel.`Ceased On`)) return *  UNION  match d=(c:Group{id:123})-[r:Member_Of*]-gt;(p:Group) with d, RELATIONSHIPS(d) as rels WHERE NONE(rel in rels WHERE EXISTS(rel.`Ceased On`)) return *  UNION  match d=(s:Group{id:123})lt;-[r:Member_Of*]-(p:Group)lt;-[r1: Member_Of*]-(c:Person) with d, RELATIONSHIPS(d) as rels where NONE(rel in rels WHERE EXISTS(rel.`Ceased On`)) return *  

В приведенном выше запросе шифра исходной вершиной является группа с идентификатором «123», поэтому для входящего и исходящего ребра я создал следующий запрос gremlin.

 g.V().hasLabel('Group').has('id',123)  union(  __.inE('Member_Of').values('Name'),   __.outE('Member_Of').values('Name')) .path()   

Теперь мне нужно пересечь входящее ребро для вершины, которая является входящей вершиной для исходной вершины в приведенном выше запросе, где я путаюсь с синтаксисом объединения.

Пожалуйста, помогите, спасибо 🙂

Комментарии:

1. Когда вы говорите, что столкнулись с проблемой — в чем проблема? Как далеко ты продвинулся с Гремлином до сих пор?

2. Привет @KelvinLawrence, я попытался объяснить немного больше, отредактировав вопрос. Спасибо

Ответ №1:

Эта часть запроса Cypher

 match d=(s:Group{id:123})lt;-[r:Member_Of*]-(p:Group)lt;-[r1:Member_Of*]-(c:Person)  

В Гремлине может быть выражено как

 g.V().has('Group','id',123).  repeat(inE('Member_Of').outV()).until(hasLabel('G')).  repeat(inE('Member_Of').outV()).until(hasLabel('Person')).  path().  by(elementMap())  

Если на самом деле не задействовано несколько переходов (т. Е. в шифре, если вам действительно не нужно»*»), вы можете удалить repeat конструкцию и просто сохранить inE outV шаги и. В любом случае, этот кусочек Гремлина даст вам узлы и ребра (отношения) вместе со всеми их свойствами и т. Д., Поскольку путь будет содержать их elementMap .

Обратите внимание, что прямой порт от Cypher до Gremlin может не в полной мере использовать преимущества целевой базы данных. Например, многие магазины с поддержкой Gremlin позволяют предоставлять пользовательские (реальные) Значения идентификаторов. Это делает запросы намного более эффективными, так как вы можете использовать что-то вроде этого:

 g.V('123')  

чтобы непосредственно найти вершину.

Пожалуйста, добавьте комментарий ниже, если это не полностью разблокирует вас.

ОБНОВЛЕНО: 2021-10-29

Я использовал набор данных о воздушных маршрутах, чтобы проверить, работает ли шаблон запроса, используя этот запрос:

 g.V().has('airport','code','AUS').  repeat(inE('contains').outV()).until(hasLabel('country')).limit(1).  repeat(outE('contains').inV()).until(hasLabel('airport')).limit(3).  path().  by(elementMap())  

Комментарии:

1. Привет @KelvinLawrence, после добавления некоторых пропущенных скобок появляется следующая ошибка. { «detailedMessage»: «Повторение()-обход не был определен: Повторный шаг(до тех пор, пока([NeptuneMemoryTrackerStep, NeptuneHasStep([~label.eq(персона)])]),излучение(ложь))», «Запрос»: «43y4uy3-a28f-4592-aae6-7r7r7rjrj», «код»: «Исключение InternalFailureException» }

2. Извините за родителей — я обновил запрос в ответе. Этот работает для меня без ошибок. Не могли бы вы, пожалуйста, опубликовать измененную версию запроса, который выдает вам ошибку?

3. Спасибо Келвину Лоуренсу, это работает, и я поставил круглую скобку в конце шага повтора до тех пор, пока не возникнет проблема, теперь она работает нормально.

4. Привет, Келвин, я опубликовал полный гремлинский перевод запроса на шифр. Пожалуйста, посмотрите и прокомментируйте.

Ответ №2:

Ниже приводится полная замена запроса cypher запросом gremlin.

 g.V().has('Group','id',123). //source vertex   union(  //Following represent incoming Member_Of edge towards source vertex from Person Node, untill the last node in the chain  repeat(inE('Member_Of').outV()).until(hasLabel('Person')),  //Following represent incoming Member_Of edge from Group to source vertex and edge outwards from same Group, untill the last node in the chain  repeat(inE('Member_Of').outV().hasLabel('Group').simplePath()).until(inE().count().is(0)).  repeat(outE('Member_Of').inV().hasLabel('Group').simplePath()).until(inE().count().is(0)),  //Following represent outgoing Member_Of edge from source vertex to another Group node, untill the last node in the chain  repeat(outE('Member_Of').inV().hasLabel('Group').simplePath()).until(outE().count().is(0)),  //Following represent incoming Member_Of edge from Group to source vertex and incoming edge from person to Group untill the last node in the chain  repeat(inE('Member_Of').outV().hasLabel('Group').simplePath()).until(inE().count().is(0)).  repeat(inE('Member_Of').outV().hasLabel('Person').simplePath()).until(inE().count().is(0))  ).  path().by(elementMap())