Neo4j/Cypher匹配遍历分支中的前n个节点
Neo4j/Cypher matching first n nodes in the traversal branch
我有图表:(:Sector)<-[:BELONGS_TO]-(:Company)-[:PRODUCE]->(:Product)
.
我正在寻找下面的查询。
从 (:Sector)
开始。然后匹配该行业的前 50 家公司,并为每家公司匹配前 10 种产品。
第一个限制很简单。但是限制产品呢。
密码可以吗?
更新
正如@cybersam 在下面建议的那样,查询将 return 有效结果
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH c
LIMIT 50
MATCH (c)-[:PRODUCE]->(p:Product)
WITH c, (COLLECT(p))[0..10] AS products
RETURN c, products
但是,此解决方案无法扩展,因为它仍然遍历每个公司的所有产品。在每个公司产品收集后应用切片。随着产品数量的增加,查询性能会下降。
此查询的每个返回行将包含:一个部门、其公司之一(每个部门最多 50 个)以及该公司最多 10 种产品的集合:
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH s, (COLLECT(c))[0..50] AS companies
UNWIND companies AS company
MATCH (company)-[:PRODUCE]->(p:Product)
WITH s, company, (COLLECT(p))[0..10] AS products;
使用APOC Procedures更新一些解决方案。
limiting results per row 上的这篇 Neo4j 知识库文章介绍了几种不同的方法。
一种方法是使用apoc.cypher.run()
每行执行一个有限的子查询。应用于有问题的查询,这将起作用:
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH c
LIMIT 50
CALL apoc.cypher.run('MATCH (c)-[:PRODUCE]->(p:Product) WITH p LIMIT 10 RETURN collect(p) as products', {c:c}) YIELD value
RETURN c, value.products AS products
提到的另一种选择是使用 APOC 路径扩展程序,在终止过滤器和限制上提供标签:
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH c
LIMIT 50
CALL apoc.path.subgraphNodes(c, {maxLevel:1, relationshipFilter:'PRODUCE>', labelFilter:'/Product', limit:10}) YIELD node
RETURN c, collect(node) AS products
我有图表:(:Sector)<-[:BELONGS_TO]-(:Company)-[:PRODUCE]->(:Product)
.
我正在寻找下面的查询。
从 (:Sector)
开始。然后匹配该行业的前 50 家公司,并为每家公司匹配前 10 种产品。
第一个限制很简单。但是限制产品呢。
密码可以吗?
更新
正如@cybersam 在下面建议的那样,查询将 return 有效结果
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH c
LIMIT 50
MATCH (c)-[:PRODUCE]->(p:Product)
WITH c, (COLLECT(p))[0..10] AS products
RETURN c, products
但是,此解决方案无法扩展,因为它仍然遍历每个公司的所有产品。在每个公司产品收集后应用切片。随着产品数量的增加,查询性能会下降。
此查询的每个返回行将包含:一个部门、其公司之一(每个部门最多 50 个)以及该公司最多 10 种产品的集合:
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH s, (COLLECT(c))[0..50] AS companies
UNWIND companies AS company
MATCH (company)-[:PRODUCE]->(p:Product)
WITH s, company, (COLLECT(p))[0..10] AS products;
使用APOC Procedures更新一些解决方案。
limiting results per row 上的这篇 Neo4j 知识库文章介绍了几种不同的方法。
一种方法是使用apoc.cypher.run()
每行执行一个有限的子查询。应用于有问题的查询,这将起作用:
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH c
LIMIT 50
CALL apoc.cypher.run('MATCH (c)-[:PRODUCE]->(p:Product) WITH p LIMIT 10 RETURN collect(p) as products', {c:c}) YIELD value
RETURN c, value.products AS products
提到的另一种选择是使用 APOC 路径扩展程序,在终止过滤器和限制上提供标签:
MATCH (s:Sector)<-[:BELONGS_TO]-(c:Company)
WITH c
LIMIT 50
CALL apoc.path.subgraphNodes(c, {maxLevel:1, relationshipFilter:'PRODUCE>', labelFilter:'/Product', limit:10}) YIELD node
RETURN c, collect(node) AS products