#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())