我和(供应商)有关系 - [供应] - (产品)。 鉴于产品清单,我如何找到供应清单中每种产品的供应商?
答案 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
将自动重复删除行。