1.Ответ на первоначальный вопрос
1.1 Создание вашего графика
Для простоты возможных дальнейших ответов и решений я отмечу мое утверждение создания графика:
CREATE
(:Person {name: 'Ryan'})-[:TRADES]->(fish:Product {name: 'Fish'}),
(:Person {name: 'Ken'})-[:TRADES]->(fish),
(:Person {name: 'Mary'})-[:TRADES]->(fish),
(john:Person {name: 'John'})-[:TRADES]->(fish),
(ian:Person {name: 'Ian'})-[:TRADES]->(fish),
(ian)-[:TRADES]->(pork:Product {name: 'Pork'}),
(john)-[:TRADES]->(pork),
(ian)-[:TRADES]->(oil:Product {name: 'Oil'}),
(ian)-[:TRADES]->(pasta:Product {name: 'Pasta'}),
(ian)-[:TRADES]->(rice:Product {name: 'Rice'}),
(ian)-[:TRADES]->(milk:Product {name: 'Milk'}),
(ian)-[:TRADES]->(orange:Product {name: 'Orange'}),
(john)-[:TRADES]->(oil),
(john)-[:TRADES]->(rice),
(john)-[:TRADES]->(pasta),
(john)-[:TRADES]->(orange),
(john)-[:TRADES]->(milk),
(peter:Person {name: 'Peter'})-[:TRADES]->(rice),
(peter)-[:TRADES]->(pasta),
(peter)-[:TRADES]->(orange),
(peter)-[:TRADES]->(oil),
(peter)-[:TRADES]->(milk),
(peter)-[:TRADES]->(apple:Product {name: 'Apple'}),
(ian)-[:TRADES]->(apple);
1.2 Решение
MATCH (person:Person)-[:TRADES]->(product:Product)
WITH person.name AS personName, count(product) AS amount
WHERE amount >=5
RETURN personName, amount;
- первая строка: определение шаблона сопоставления
- вторая строка: количество продуктов на человека
- третья строка: фильтр для количества привезенных продуктов
- четвертая строка: вывести результат
1,3 Результат
╒════════════╤════════╕
│"personName"│"amount"│
╞════════════╪════════╡
│"John" │7 │
├────────────┼────────┤
│"Ian" │8 │
├────────────┼────────┤
│"Peter" │6 │
└────────────┴────────┘
2.Ответ на новый вопрос и требования
2.1 Решение
MATCH path=(sourcePerson:Person)-[:TRADES]->(product:Product)<-[:TRADES]-(targetPerson:Person)
WITH sourcePerson, targetPerson, count(path) AS pathAmount, collect(product.name) AS products
WHERE pathAmount >= 5 AND id(sourcePerson) > id(targetPerson)
RETURN DISTINCT products, collect(sourcePerson.name) AS sourcePersons, collect(targetPerson.name) AS targetPersons;
2.2 Результат
╒════════════════════════════════════════════════════╤═══════════════╤═══════════════╕
│"products" │"sourcePersons"│"targetPersons"│
╞════════════════════════════════════════════════════╪═══════════════╪═══════════════╡
│["Tomato","Cabbage","Plum","Book","Fish"] │["Mary"] │["Ken"] │
├────────────────────────────────────────────────────┼───────────────┼───────────────┤
│["Milk","Orange","Pasta","Rice","Oil"] │["Peter"] │["John"] │
├────────────────────────────────────────────────────┼───────────────┼───────────────┤
│["Milk","Orange","Pasta","Rice","Oil","Pork","Fish"]│["Ian"] │["John"] │
├────────────────────────────────────────────────────┼───────────────┼───────────────┤
│["Apple","Orange","Milk","Rice","Pasta","Oil"] │["Peter"] │["Ian"] │
└────────────────────────────────────────────────────┴───────────────┴───────────────┘
2.3 Примечание
Показанный результат немного отличается от вашегоожидание, поскольку для отношений Ian->Apple<-Peter
, John->Pork<-Ian
и John->Fish<-Ian
ваше требование «лица, купившие более четырех продуктов» также выполнено и, таким образом, создает отдельный кластер.
3.Альтернатива
Если тонкая гранулированная кластеризация не соответствует вашим требованиям, вы также можете отменить требование «куплено> 4 продуктов».В этом случае решение будет выглядеть следующим образом:
3.1 Решение
CALL algo.louvain.stream('', '', {})
YIELD nodeId, community
WITH algo.getNodeById(nodeId) AS node, community
ORDER BY community
WITH community, collect(node) AS nodes
WITH
community,
[x IN nodes WHERE ('Person' IN labels(x)) | x.name] AS persons,
[x IN nodes WHERE ('Product' IN labels(x)) | x.name] AS products
RETURN community, persons, products;
- строка 1: вызовите Neo4j Graph Algorithms процедура алгоритм Лувена
- строка 2: определить переменные результата
- строка 3: извлечь значения из потока результатов
- строка 4: упорядочить значения сообщества
- строка8: отфильтровать результирующие узлы по метке
Person
- , строка 9: отфильтровать результирующие узлы по метке
Product
- , строка 10: отрендерить вывод
3.2 Результат
╒═══════════╤══════════════════════╤═════════════════════════════════════════════════════════════╕
│"community"│"persons" │"products" │
╞═══════════╪══════════════════════╪═════════════════════════════════════════════════════════════╡
│0 │["Ryan","Ken","Mary"] │["Fish","Book","Plum","Cabbage","Tomato","Pineapple","Pizza"]│
├───────────┼──────────────────────┼─────────────────────────────────────────────────────────────┤
│1 │["John","Ian","Peter"]│["Pork","Oil","Pasta","Rice","Milk","Orange","Apple"] │
└───────────┴──────────────────────┴─────────────────────────────────────────────────────────────┘
Если вы предпочитаете сам узел вместо имен, просто удалите обе части | x.name
в последнем предложении WITH
.