2017-02-14 19 views
3

Я использую Neo4j CE 3.1.1, и у меня есть отношения ПИСАНИЯ между авторами и книгами. Я хочу найти N (например, N = 10, например) книг с наибольшим числом авторов. После несколько примеров, которые я нашел, я пришел с запросом:Neo4j: запрос, чтобы найти узлы с наибольшими отношениями и их подключенные узлы

MATCH (a)-[r:WRITES]->(b) 
RETURN r, 
COUNT(r) ORDER BY COUNT(r) DESC LIMIT 10 

Когда я выполнить этот запрос в браузере Neo4j я получаю 10 книг, но они не похожи на те, написанных большинством авторов, так как они показывают только несколько отношений WRITES с авторами. Если изменить запрос к

MATCH (a)-[r:WRITES]->(b) 
RETURN b, 
COUNT(r) ORDER BY COUNT(r) DESC LIMIT 10 

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

MATCH()-[r:WRITES]->(b) 
WHERE b.title="Title of a book with many authors" 
RETURN r 

Что я делаю неправильно? Почему первый запрос работает не так, как ожидалось?

ответ

3

Скопление только контекст на основе столбцов без агрегации, и с матчем, уникальные отношения будут происходить только один раз в результатах.

Таким образом, ваш первый запрос просит каждое отношение в ряде, и подсчет этого конкретного отношения, которое 1.

Вы можете переписать это в нескольких различных способах.

Один предназначен для авторов и порядок по размеру списка автора:

MATCH (a)-[:WRITES]->(b) 
RETURN b, COLLECT(a) as authors 
ORDER BY SIZE(authors) DESC LIMIT 10 

Вы всегда можете собрать автора и его отношения, если сами отношения вам интересно.

EDIT

Если вам посчастливилось иметь ярлыки на ваших узлов (вы абсолютно ДОЛЖНЫ иметь этикетки на разных узлах), вы можете попробовать другой подход путем сопоставления ко всем книгам, получая размер входящего: ПИШЕТ отношения для каждой книги, приказав и ограничение на что, а затем выполняя матч авторов:

MATCH (b:Book) 
WITH b, SIZE(()-[:WRITES]->(b)) as authorCnt 
ORDER BY authorCnt DESC LIMIT 10 
MATCH (a)-[:WRITES]->(b) 
RETURN b, a 

вы можете собрать на авторов и/или вернуть отношения, а также, в зависимости от того, что вам нужно от выхода.

+0

Большое спасибо! – st1led

+0

Несомненно! Хотя вы можете сначала профилировать запросы, первый, который я дал, вероятно, не будет таким же результативным, поскольку он собирает тонны на более крупном графике. – InverseFalcon

0

Вы очень близки: после сортировки необходимо заново открыть авторов. Например:

MATCH (a:Author)-[r:WRITES]->(b:Book) 
WITH b, 
    COUNT(r) AS authorsCount 
    ORDER BY authorsCount DESC LIMIT 10 
MATCH (b)<-[:WRITES]-(a:Author) 
RETURN b, 
     COLLECT(a) AS authors 
     ORDER BY size(authors) DESC 
+0

Я пробовал этот запрос, и он также работает. У меня нет больших данных, но почему-то я чувствую, что он менее масштабируемый, чем первый в принятом ответе (только одно предложение MATCH против 2). Тем не менее, я не эксперт по внутренним разработкам/оптимизации neo4j, и это также отлично работает. – st1led

+0

@ st1led Вы всегда можете ПРОФИЛЬ запросов, чтобы убедиться. Тем не менее, второй MATCH - после LIMIT 10, поэтому он не так тяжел, как первый, поэтому на самом деле выступления должны быть похожими. – InverseFalcon