Neo4J: Как я могу найти, если существует путь, проходящий через несколько узлов, указанных в списке? - PullRequest
0 голосов
/ 13 октября 2019

У меня есть график узлов с отношением СЛЕДУЮЩАЯ с последовательностью 2 свойств ( s ) и положением ( p ). Например:

N1-[NEXT{s:1, p:2}]-> N2-[NEXT{s:1, p:3}]-> N3-[NEXT{s:1, p:4}]-> N4 

Узел N может иметь несколько исходящих Next отношений с различными значениями свойств.

Дан список имен узлов, например, [N2, N3, N4] представляющий последовательный путь, я хочу проверить, содержит ли граф узлы и связаны ли эти узлы с отношением Далее по порядку.

Например, если список содержит [N2, N3, N4], проверьте, существует ли связь Далее между узлами N2, N3 и между N3, N4.

Кроме того, я хочу убедиться, что узлы являются частью одной и той же последовательности, поэтому свойство s одинаково для каждого отношения Далее . Чтобы убедиться, что порядок поддерживается, мне нужно проверить, является ли свойство p инкрементным. Это означает, что значение p во взаимосвязи между N2 -> N3 равно 3 , а значение p между N3-> N4 равно (3 + 1) = 4 и т. Д.

Я попытался с помощью APOC извлечь возможные пути из начального узла N с помощью python (library: neo4jrestclient), а затем обработать пути вручную, чтобы проверить, существует ли последовательностьиспользуя следующий запрос:

q = "MATCH (n: Node) WHERE n.name = 'N' CALL apoc.path.expandConfig (n {relationsFilter: 'NEXT>', maxLevel: 4}) YIELD path RETURN path "

results = db.query (q, data_contents = True)

Однако выполнение запроса заняло некоторое время, и я в итоге остановил запрос. Есть идеи?

1 Ответ

0 голосов
/ 15 октября 2019

Это немного сложно.

Во-первых, предварительно сопоставьте узлы в пути. Здесь мы можем использовать собранные узлы, чтобы быть белым списком для узлов в пути

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

UNWIND $names as name
MATCH (n:Node {name:name})
WITH collect(n) as nodes
WITH nodes, nodes[0] as start, tail(nodes) as tail, size(nodes)-1 as depth
CALL apoc.path.expandConfig(start, {whitelistNodes:nodes, minLevel:depth, maxLevel:depth, relationshipFilter:'NEXT>'}) YIELD path
WHERE all(index in range(0, size(nodes)-1) WHERE nodes[index] = nodes(path)[index])
// we now have only paths with the given nodes in order
WITH path, relationships(path)[0].s as sequence
WHERE all(rel in tail(relationships(path)) WHERE rel.s = sequence)
// now each path only has relationships of common sequence
WITH path, apoc.coll.pairsMin([rel in relationships(path) | rel.p]) as pairs
WHERE all(pair in pairs WHERE pair[0] + 1 = pair[1])
RETURN path
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...