在Neo4j中查找集群 [英] Find cluster in Neo4j
问题描述
我有一个neo4j数据库,如下所示.
Hi I have a neo4j database, similar to below.
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组).在所有可能的项目中
I would like to query the names who buy 5 or more same items. (In this case, it's Peter, John and Ian as group1, Ken and Mary as Group2). In for all possible items
增加了欲望输出
我的Desire输出类似于以下内容
My Desire output is similar to below
推荐答案
1.回答第一个问题
1.1创建图形
为便于进一步解答和解决方案,我注意到了我的图形创建语句:
1. Answer for initial question
1.1 Creating your graph
For the ease of possible further answers and solutions I note my graph creating statement:
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);
MATCH (person:Person)-[:TRADES]->(product:Product)
WITH person.name AS personName, count(product) AS amount
WHERE amount >=5
RETURN personName, amount;
- 第一行:定义匹配模式
- 第二行:每人计数产品
- 第三行:带入产品数量的过滤器
- 第四行:呈现结果
- first line: defining the matching pattern
- second line: count products per person
- third line: filter for brought products amount
- fourth line: render the result
╒════════════╤════════╕
│"personName"│"amount"│
╞════════════╪════════╡
│"John" │7 │
├────────────┼────────┤
│"Ian" │8 │
├────────────┼────────┤
│"Peter" │6 │
└────────────┴────────┘
2.回答新问题和要求
2.1解决方案
2. Answer for new question and requirements
2.1 Solution
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
,您的购买四个以上产品的人"的要求也得到了满足,因此创建了一个单独的类.
2.3 Note
The result shown differs a little from your expectation, since for the relations Ian->Apple<-Peter
, John->Pork<-Ian
and John->Fish<-Ian
your requirement "persons who bought more than four products" is met also and thus it creates a separate cluster.
如果精细的颗粒聚类不满足您的要求,您也可以放弃购买> 4个产品"的要求.在这种情况下,解决方案将如下所示:
If the fine granular clustering does not meet your requirements, you can also drop the "bought >4 products" requirement. In this case the solution would look like this:
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图算法过程
- line 1: call the Neo4j Graph Algorithms procedure Louvain algorithm
- line 2: define result variables
- line 3: retrieve values from the result stream
- line 4: order the community values
- line 8: filter the resulting nodes for label
Person
- line 9: filter the resulting nodes for label
Product
- line 10: render the output
╒═══════════╤══════════════════════╤═════════════════════════════════════════════════════════════╕ │"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"] │ └───────────┴──────────────────────┴─────────────────────────────────────────────────────────────┘
如果您更喜欢节点本身而不是名称,只需删除最后一个
WITH
子句中的两个| x.name
部分.If you prefer the node itself instead of the names, just remove both
| x.name
parts in the lastWITH
clause.这篇关于在Neo4j中查找集群的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!