给定一个节点列表,如何找到连接到Neo4j列表中每个节点的节点

时间:2016-10-10 21:19:29

标签: neo4j cypher graph-databases

我和(供应商)有关系 - [供应] - (产品)。 鉴于产品清单,我如何找到供应清单中每种产品的供应商?

2 个答案:

答案 0 :(得分:3)

Tore的答案是一种很好的通用方法,只要表现良好,就应该受到青睐。

但如果有大量的供应商,这个查询可能会遇到性能问题,因为它必须对数据库中的每个供应商进行WHERE ALL测试。

我们可以通过查找列表中某个产品的所有供应商来弥补这一点,并将其作为供应商来评估,而不是每个供应商。

WITH listOfProducts, HEAD(listOfProducts) as prod1
MATCH (supplier:Supplier)-[:supplies]->(prod1)
WHERE ALL(product IN list_of_products WHERE (supplier) - [:supplies] - (product) )
RETURN supplier

答案 1 :(得分:0)

WITH prods_a, prods_b, HEAD(prods_a) AS prod1
MATCH (supplier1:Supplier) - [:supplies] - (prod1)
WHERE ALL(prod_a IN prods_a WHERE (supplier1) - [:supplies] - (prod_a) )
WITH DISTINCT prods_b, HEAD(prods_b) AS prod2, COLLECT(supplier1) AS supplies_a
MATCH (supplier2:Supplier) - [:supplies] -(prod2)
WHERE ALL(prod_b IN prods_b WHERE (supplier2) - [:supplies] - (prod_b) )
WITH supplies_a, COLLECT(supplier2) AS supplies_b
WITH [x IN supplies_a | {supplier: x, supplies: 'products_a'}] + [y IN supplies_b | {supplier: y, supplies: 'products_b'}] AS result_dicts
UNWIND result_dicts AS result_dict
WITH result_dict.supplier AS supplier, result_dict.supplies AS supplies
RETURN supplier, COLLECT(DISTINCT supplies)

尝试保留两个单独的列表要困难得多,就像以任何有意义的方式聚合结果一样。但是,这遵循与InverseFalcon优化查询相同的基本匹配和过滤器结构。然而,有严重的恶作剧将两者结合起来并进行分析以找到交叉点。

P.S。严格的答案是执行UNION查询,但这需要在Cypher之外进行分析。

WITH listOfProductsA, HEAD(listOfProductsA) as prod1
MATCH (supplier:Supplier)-[:supplies]->(prod1)
WHERE ALL(product IN list_of_products WHERE (supplier) - [:supplies] - (product) )
RETURN supplier, 'supplies_a'
UNION
WITH listOfProductsb, HEAD(listOfProductsb) as prod1
MATCH (supplier:Supplier)-[:supplies]->(prod1)
WHERE ALL(product IN list_of_products WHERE (supplier) - [:supplies] - (product) )
RETURN supplier, 'supplies_b'

当然,在UNION之后的开头和右边插入匹配逻辑。如果您真的只想要提供至少一个且没有其他上下文的供应商列表,您也可以删除字符串,UNION将自动重复删除行。