Neo4j Cypher: получите сеть общих друзей

Я считаю, что то, что у меня есть, должно быть очень простым, но по какой-то причине я не продвигаюсь вперед. У меня классическая настройка социальной сети, где пользователи могут дружить друг с другом. Я знаю, что хочу визуализировать сеть пользователя с помощью D3.js

Для этого очевидно, как получить друзей

user -[:friend]- friend

Теперь я также хочу отобразить связи между друзьями пользователя, чтобы они хорошо сгруппировались в принудительно ориентированном графе. Однако это моя текущая проблема, так как я хотел бы узнать, как набор «друг» связан друг с другом. я сначала подумал

with friend
match friend -[connection:friend]- friend

будет работать, но явно не работает. Кажется, я упускаю из виду одну очень очевидную вещь, но я не уверен, что именно.

РЕДАКТИРОВАТЬ: Гремлин тоже приветствуется, может быть более производительным, если его более обходной/явный


person nambrot    schedule 01.03.2013    source источник
comment
не делайте последнее утверждение после ПОИСКПОЗ в with friend ..., а поместите его непосредственно в фазу ПОИСКПОЗ, например MATCH user-[:friend]-firend-[connection:friend]-friend2 . это работает для вас?   -  person ulkas    schedule 01.03.2013
comment
спасибо за Ваш ответ. Я знаю, что именно так я могу получить друзей друзей, но это расширенный набор того, что я хочу. Мне нужны только друзья друзей, которые также являются друзьями пользователя, и это также необязательно. если вы предполагаете, что у каждого есть 100 друзей, мне нужен пользователь, его 100 друзей и то, как эти 101 человек дружат друг с другом   -  person nambrot    schedule 01.03.2013


Ответы (1)


Возможно, это вдохновит вас на решение с использованием Gremlin. Я адаптировал вашу задачу к стандартному графу игрушек TinkerPop. Я решил выяснить следующее:

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

Итак, я начал с:

gremlin> g = TinkerGraphFactory.createTinkerGraph()              
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).outE.as('x').inV.loop(2){it.loops<3}{true}.select
==>[x:e[7][1-knows->2]]
==>[x:e[8][1-knows->4]]
==>[x:e[9][1-created->3]]
==>[x:e[10][4-created->5]]
==>[x:e[11][4-created->3]]

Для вершины с идентификатором 1 получите все исходящие ребра, затем зациклите это снова, чтобы получить ребра друзей, и, наконец, выберите значения шага «x». Это позволяет вам, по крайней мере, узнать, что представляет собой этот подграф вокруг g.v(1), но когда я прочитал ваш вопрос, вы хотели сделать еще один шаг, чтобы ограничить подграф только теми вершинами, которые подключены к g.v(1). Глядя на результаты, e[10] действительно не следует включать, потому что между g.v(1) и g.v(5) нет границы.

Я дополнительно уточнил запрос, чтобы исключить эту связь из подграфа:

gremlin> x=[g.v(1)];g.v(1).out.aggregate(x).back(2).outE.filter{x.contains(it.inV.next())}.as('e').inV.loop(3){it.loops<3}{true}.select 
==>[e:e[7][1-knows->2]]
==>[e:e[8][1-knows->4]]
==>[e:e[9][1-created->3]]
==>[e:e[11][4-created->3]]

Таким образом, вышеизложенное в основном говорит,

  • инициализируйте список x, который будет содержать все вершины, которые должны содержаться в подграфе.
  • g.v(1).out.aggregate(x) в основном помещает все вершины в «x», которые я хочу в подграфе, в дополнение к той, с которой я ее инициализировал
  • вернуться к началу обхода и найти ребра, которые содержат вершины в x, затем зациклить его, как и раньше, и выбрать значение шага «e», которое является списком ребер.

Теперь вы можете видеть, что e[10] больше нет в результатах. Отсюда вы можете довольно легко построить вывод для визуализации.

person stephen mallette    schedule 02.03.2013