Neo4j: создание путей / подграфов из виртуальных отношений APOC для потоковой передачи в Gephi

У меня есть база данных Neo4j, состоящая из узлов Film и Person, связанных ACTED_IN отношениями. Используя APOC, мне удалось создать набор виртуальных ACTED_WITH отношений непосредственно между Person узлами, отражающих тот факт, что они косвенно связаны через Film, в котором они оба появились:

MATCH (a:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(b:Person)
WITH a, b
CALL apoc.create.vRelationship(a, 'ACTED_WITH', {}, b) YIELD rel
RETURN a, rel, b

Кажется, это отражает непрямые отношения, которые я ищу. Теперь я хочу передать результаты в Gephi для визуализации. Но соответствующая функция APOC принимает аргумент paths. Итак, это работает:

MATCH path = ()-[:ACTED_IN]->()
WITH collect(path) AS paths
CALL apoc.gephi.add(null, 'workspace0', paths) YIELD nodes, relationships, time
RETURN nodes, relationships, time

Как я могу создать набор путей из виртуальных отношений, полученных в первом блоке кода, для передачи в Gephi, как во втором? (Или есть лучший способ справиться с подобными случаями?)


person rjww    schedule 15.08.2018    source источник


Ответы (1)


Данные для apoc.gephi.add процедуры могут быть instanceof: Node, Relationship, Path, Iterable, Map, Iterator, Object.

Так должно получиться так:

MATCH (a:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(b:Person) WHERE ID(a) > ID(b) 
WITH DISTINCT a, b
CALL apoc.create.vRelationship(a, 'ACTED_WITH', {}, b) YIELD rel AS rel1
CALL apoc.create.vRelationship(b, 'ACTED_WITH', {}, a) YIELD rel AS rel2
WITH collect(rel1) + collect(rel2) + collect(a) + collect(b) AS data
CALL apoc.gephi.add(null, 'workspace0', data) YIELD nodes, relationships, time
RETURN nodes, relationships, time

Обновление: если вам нужны веса, вы можете просто агрегировать по фильмам:

MATCH (a:Person)-[:ACTED_IN]->(M:Movie)<-[:ACTED_IN]-(b:Person) WHERE ID(a) > ID(b) 
WITH a, b, 
     count(M) as vWeight
CALL apoc.create.vRelationship(a, 'ACTED_WITH', {weight: vWeight}, b) YIELD rel AS rel1
CALL apoc.create.vRelationship(b, 'ACTED_WITH', {weight: vWeight}, a) YIELD rel AS rel2
WITH collect(rel1) + collect(rel2) + collect(a) + collect(b) AS data
CALL apoc.gephi.add(null, 'workspace0', data) YIELD nodes, relationships, time
RETURN nodes, relationships, time
person stdob--    schedule 15.08.2018
comment
Это здорово, спасибо. Что-то вроде расширения моего первоначального вопроса, но есть ли хороший способ свернуть параллельные отношения между узлами вместе? (Я имею в виду дублированные связи между узлами, возникающие, когда два актера появляются вместе более чем в одном фильме.) - person rjww; 16.08.2018
comment
@rjww Зависит от ваших целей. На мой взгляд, должно быть одно отношение к собственности по количеству общих фильмов. - person stdob--; 16.08.2018
comment
Да, в идеале должна быть одна виртуальная связь (или взаимная пара, я полагаю, учитывая, что графы Neo4j ориентированы) между совместно появляющимися актерами со свойством веса, которое является подсчетом количества фильмов, в которых они появляются вместе. Конечная цель - внедрить что-то подобное в Gephi, чтобы я мог создавать исследовательские визуализации с разными мерами центральности и т. Д. - person rjww; 16.08.2018
comment
@rjww Для весов используйте функцию агрегирования count. См. Дополнение к ответу. - person stdob--; 16.08.2018
comment
Какое возможное решение для слияния повторяющихся виртуальных отношений между двумя узлами? - person daudichya; 23.12.2019
comment
@daudichya Можете пояснить свой вопрос на примере? - person stdob--; 23.12.2019
comment
@stdob, пожалуйста, перейдите по ссылке под заголовком stackoverflow.com/questions/59465211/ Спасибо за проявленный интерес! - person daudichya; 25.12.2019