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 Note
显示的结果与您的期望略有不同,因为对于关系Ian->Apple<-Peter
, John->Pork<-Ian
and 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 图算法 https://neo4j.com/docs/graph-algorithms/3.5/程序鲁汶算法 https://neo4j.com/docs/graph-algorithms/current/algorithms/louvain/
- 第 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
clause.