Найти кластер в Neo4j - PullRequest
       15

Найти кластер в Neo4j

0 голосов
/ 05 декабря 2018

Привет У меня есть база данных neo4j, похожая на приведенную ниже.

CREATE
  (:Person {name: 'Ryan'})-[:TRADES]->(fish:Product {name: 'Fish'}),
  (ken:Person {name: 'Ken'})-[:TRADES]->(fish),
  (mary:Person {name: 'Mary'})-[:TRADES]->(fish),
  (john:Person {name: 'John'})-[:TRADES]->(fish),
  (ken)-[:TRADES]->(book:Product {name: 'Book'}),
  (ken)-[:TRADES]->(plum:Product {name: 'Plum'}),
  (ken)-[:TRADES]->(cabbage:Product {name: 'Cabbage'}),
  (ken)-[:TRADES]->(tomato:Product {name: 'Tomato'}),
  (ken)-[:TRADES]->(pineapple:Product {name: 'Pineapple'}),
  (mary)-[:TRADES]->(Pizza:Product {name: 'Pizza'}),
  (mary)-[:TRADES]->(book),
  (mary)-[:TRADES]->(plum),
  (mary)-[:TRADES]->(cabbage),
  (mary)-[:TRADES]->(tomato),
  (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);

Я хотел бы запросить имена, которые покупают 5 или более одинаковых предметов.(В данном случае это Питер, Джон и Ян в качестве группы 1, Кен и Мэри в качестве группы 2).Для всех возможных предметов

enter image description here

[EDITED] Добавлен вывод желаний

Вывод My Desire аналогичен приведенному ниже enter image description here

1 Ответ

0 голосов
/ 06 декабря 2018

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);

Graph

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...