Я новичок в Neo4j и Cypher и пишу о своей BA-Thesis, в которой я сравниваю RDBMS с Neo4j Graph Database в случае социальных сетей. Я определил некоторые запросы в SQL и Cypher для теста производительности над JDBC и REST API в JMETER. Тем не менее, у меня есть проблема, объявляющая запрос Cypher, чтобы получить узлы, которые являются общими друзьями друзей для определенного узла.
Мой первый подход был таким:
MATCH (me:Enthusiast {Id: 488})-[:abonniert]->(f:Enthusiast)-[:abonniert]->(fof:Enthusiast)<-[:abonniert]-(f) RETURN o
Наверное, вы довольно близки к заявлению Cypher. Я предполагаю, что “общий друг на 2-й степени” означает, что я – общий друг с кем-то, целью которого является и общий друг?
Если это так (сокращение меток и типов отношений для чтения):
MATCH
(me:En {Id: 488})-[:abonniert]->(f:En)-[:abonniert]->(fof:En),
(fof)-[:abonniert]->(f)-[:abonniert]->me
RETURN fof
было бы неплохо, если бы вы могли создать примерный сценарий на http://console.neo4j.org/. я бы также опустил направление отношений.
MATCH (me:Enthusiast {Id: 488})-[:abonniert]->(f:Enthusiast),
(f)-[:abonniert]-(x:Enthusiast)-[:aboniert]-(y:Enthusiast)
WHERE f--y AND Id(y) <> 488
RETURN f, y, count(x) as NrMutFr
редактировать
попробуйте этот консольный запрос, работает для сценария: http://console.neo4j.org/r/tws07k
мой предыдущий запрос в этом случае был бы
MATCH (me:Enthusiast {Id: 488})-[:abonniert]->(f:Enthusiast),
(f)-[:abonniert]->(x:Enthusiast)<-[:aboniert]-(y:Enthusiast)
WHERE me--y
RETURN f, y, count(x) as NrMutFr
разница между запросом на ваш вопрос заключается в том, что вы должны закончить последний узел с новой заменой y
а не f
. чем также, при необходимости, снова совпадают, что y
с пусковым me
узел
После того, как вы подберете своих друзей, вы сможете выразить остальную часть запроса как предикат пути: сопоставьте “мои друзья”, отфильтровывайте всех, кроме “друзей моих друзей, у которых есть общий знакомый”, что соответствует так же, как “мои друзья, у которых есть друг-друг, который мой друг.
MATCH (me:Enthusiast { Id: 488 })-[:abonniert]->(f)
WHERE f-[:abonniert]-()-[:abonniert]-()<-[:abonniert]-me
RETURN f
Здесь консоль: http://console.neo4j.org/r/87n0j9. Если я неправильно понял ваш вопрос, вы можете внести изменения в эту консоль, нажмите “поделиться” и отправьте ссылку здесь, объяснив, какой результат вы ожидаете получить.
редактировать
Если вы хотите, чтобы узлы, из которых связаны два или более ваших друзей,
MATCH (me:Enthusiast { Id: 488 })-[:subscribed]->(f)-[:subscribed]->(common)
WITH common, count(common) AS cnt
WHERE cnt > 1
RETURN common
Узел, который является общим соседом ваших соседей, можно охарактеризовать как узел, к которому вы можете связаться хотя бы по двум путям. Таким образом, вы можете сопоставлять соседей соседей, подсчитывать время, в которое сопоставляется каждое “не”, и если оно сопоставляется более одного раза, это “не”, которое является общим для по крайней мере двух из ваших соседей. Если вы хотите, вы можете вернуть этот счет и упорядочить его результат как тип скоринга (поскольку это похоже на рекомендации).
MATCH (me:Enthusiast { Id: 488 })-[:subscribed]->(f)-[:subscribed]->(common)
WITH common, count(common) AS score
WHERE score > 1
RETURN common, score
ORDER BY score DESC