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