【问题标题】:Given a list of nodes, how to find the nodes that connect to every node in the list in Neo4j给定节点列表,如何在 Neo4j 中找到连接到列表中每个节点的节点
【发布时间】:2017-02-19 09:13:38
【问题描述】:

我的关系类似于(供应商)--[供应]--(产品)。 给定一个产品列表,我如何找到供应列表中所有产品的供应商?

【问题讨论】:

  • 如果结果中有多个供应商怎么办?
  • 您是否尝试通过各自的供应商输出每种产品?或者您是否正在尝试寻找能够供应所有给定产品的共同供应商?
  • @rpax 如果有多个供应商供应列表中的所有产品,我们需要找出所有供应商。
  • @InverseFalcon 我正在努力寻找能够提供所有给定产品的通用供应商。
  • 一个好的递归函数可以解决这个问题。

标签: neo4j cypher graph-databases


【解决方案1】:

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

【讨论】:

  • 这是一个很好的观点。过滤总是比寻路慢,所以尽可能先通过寻路来缩小范围。
【解决方案2】:
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 的优化查询相同的基本匹配和过滤器结构。但是,将两者结合起来并分析以找到交叉点是有严重的恶作剧的。

附:严格的答案是执行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 将自动删除重复行。

【讨论】:

  • 对不起,除此之外。假设我们有两类产品。假设 A 和 B。每个类别都有许多不同种类的产品。如何找到供应 A 或 B 的供应商?以及如何找到供应 A 和 B 的供应商?供应商不需要提供 A 或 B 中的所有产品,只要提供其中一种即可。
  • 好的,现在看更新。不过,这基本上是一个全新的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 2014-08-02
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2011-11-04
相关资源
最近更新 更多