neo4j - 在 Neo4j 中查找集群

标签 neo4j cypher

你好,我有一个 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个或更多相同商品的名称。 (在本例中,Peter、John 和 Ian 作为 group1,Ken 和 Mary 作为 Group2)。在所有可能的项目中

enter image description here

[编辑] 添加了欲望输出

我的 Desire 输出类似于下面 enter image description here

最佳答案

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<-IanJohn->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程序 Louvain algorithm
  • 第 2 行:定义结果变量
  • 第 3 行:从结果流中检索值
  • 第 4 行:整理社区值(value)观
  • 第 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条款。

关于neo4j - 在 Neo4j 中查找集群,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53629951/

相关文章:

graph - 使用Gremlin在图形中找到最短路径,从而避免了给定的顶点列表?

c# - 当一个人在 neo4j 中拥有 max(age) 等信息时,我该如何返回他的信息?

spring - Neo4j 的只读事务

java - Neo4j - 服务器返回 HTTP 响应代码 : 500 for URL: http://localhost:7474/db/data/cypher

neo4j - 使用文字映射语法和动态键的 Cypher 查询

database - Neo4j 插件损坏还是 Grails 2.4.4?

java - 如何在 Neo4j 中从节点 M 开始获得具有第 N 层方向的完整子图

java - 需要帮助将这两个 Cypher 查询转换为遍历框架

csv - Windows 上的 neo4j 如何在交互式浏览器 session 中解析 cypher 加载 csv 中的文件名路径?

neo4j - 组合多个 MATCH 密码查询的收集结果