Переключение направления на одну коллекцию ребер в запросе графа - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь найти свой путь вокруг arangodb, в основном меня интересует его графическая часть. Я пытаюсь понять одну вещь: как я могу переключать направление при обходе графа в одной коллекции ребер. Используя пример графика в https://docs.arangodb.com/3.4/AQL/Tutorial/Traversal.html#childof-relations,, как я могу получить дядю Джоффри, например что в Cypher будет (Джоффри) - [CHILDOF] -> (родитель) - [CHILDOF] -> (дедушка) <- [CHILDOF] - (дядя)? (Я ожидаю, что Тириона найдут) </p>

1 Ответ

0 голосов
/ 10 января 2019

В AQL вы не можете изменить направление, в котором вы следуете за ребрами одного и того же набора ребер в одном обходе, но вы можете выполнить последующий обход.

Например, вы пересекаете 2..2 OUTBOUND от Джоффри через своих родителей к его бабушке и дедушке, а затем пересекаете 1..1 INBOUND от бабушек и дедушек до братьев и сестер родителей (дядей и тетушек Джоффри или из приведенного примера набора данных, скорее только его дядя Тирион Ланнистер).

Game of Thrones - ChildOf Graph Visualization

Но будьте осторожны:

  • Следуя указаниям его бабушки и дедушки (здесь только Тайвин) в направлении INBOUND, вы получите не только Тириона, но и его родителей Хайме и Серсею.
  • Если бы это был одиночный обход, опция по умолчанию «uniqueEdges:« путь »предотвратила бы возвращение родителей Джоффри, потому что они уже были на пути к Тайвину.
  • Чтобы решить эту проблему, мы можем определить родителей и отфильтровать их в обходе, начиная с Тайвина в направлении INBOUND.
  • Другой улов в том, что родители Джоффри - братья и сестры. Чтобы не возвращать Тайвина дважды в обходе, начиная с Джоффри в направлении 2..2 ВНЕШНЕЕ, мы можем использовать опцию обхода uniqueVertices: "global", bfs: true (необходимо включить bfs, чтобы использовать uniqueVertices: "global").

Таким образом, полный запрос может выглядеть так:

LET joffrey = FIRST(
  FOR c IN Characters
    FILTER c.name == "Joffrey"
    LIMIT 1
    RETURN c
)
LET parents = (
  FOR v IN OUTBOUND joffrey ChildOf
    RETURN v
)
LET grandparents = (
  FOR v IN 2..2 OUTBOUND joffrey ChildOf
    OPTIONS {uniqueVertices: "global", bfs: true}
    RETURN v
)
LET unclesAndAunts = (
  FOR gp IN grandparents
    FOR v IN INBOUND gp ChildOf
      OPTIONS {uniqueVertices: "global", bfs: true} // needed?
      FILTER v NOT IN parents
      RETURN v
)
RETURN unclesAndAunts

Набор данных не имеет гендерного атрибута, поэтому вы не можете фильтровать как FILTER v NOT IN parents AND v.gender == "male", чтобы получить только его дядю, но вы поняли идею.

...