【问题标题】:Querying nodes based on relationships between two different nodes根据两个不同节点之间的关系查询节点
【发布时间】:2020-07-22 11:38:25
【问题描述】:

我有一个图,其中有两种不同类型的节点 A 和 B,通过关系 rel 连接。它的存在使得 A 的多个节点可能连接到 B 之一。 我的确切问题是这样的,假设我有 2 个 A 类型的节点 a1、a2 通过关系 rel 连接到 b1。我有与节点 b2 相关的类型 A 的节点 a3。我想找到一个包含a1、a2和a3的节点b3,然后在b3和b2、b1之间建立关系,如果它们满足一个属性(b3.prop/b2.prop>x & b3.prop/b1.prop>x )。是否可以用密码编写一个查询来处理这样的多个关系?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    这可能适用于您的场景:

    MATCH (b1:B), (b2:B)
    WHERE b1.id = 123 AND b2.id = 456
    MATCH (a1:A)-[:rel]->(b1)
    MATCH (a1)-[:rel]->(y1:B)
    WHERE y1 <> b1 AND y1 <> b2
    WITH b2, COLLECT(DISTINCT a1) AS a1s, COLLECT(DISTINCT y1) AS otherBs
    WITH b2, [b IN otherBs WHERE ALL(a IN a1s WHERE (a)-[:rel]->(b))] AS candidates
    WHERE SIZE(candidates) > 0
    MATCH (a2:A)-[:rel]->(b2)
    WITH candidates, COLLECT(a2) AS a2s
    UNWIND [c IN candidates WHERE ALL(a IN a2s WHERE (a)-[:rel]->(c))] AS b3
    RETURN b3
    

    此查询假定rel 关系从A 指向B,并且它 在有任何适当的b3 节点时返回结果。它首先创建与b1 相关的A 节点的所有可能B candidates 的列表。然后它会缩减candidates 列表,只保留与A 相关的B 节点与b2 相关。

    这个查询有很多细微差别。例如,如果 any Arel 关系到b1 的节点不具有rel 与其他一些B 节点的关系,则此 sn-p 将中止查询(这和b1b2不一样):

    MATCH (a1)-[:rel]->(b1)
    MATCH (a1)-[:rel]->(y1:B)
    WHERE y1 <> b1 AND y1 <> b2
    

    而以下对上述 sn-p 的重构只会在 all Arel 关系到 b1 的节点不具有 rel 关系时中止查询到其他一些B 节点(与b1b2 不同):

    MATCH (y1:B)<-[:rel]-(a1)-[:rel]->(b1)
    WHERE y1 <> b1 AND y1 <> b2
    

    【讨论】:

    • 这适用于特定的 2 B 对吗?我正在寻找一种方法来使用 b1 和 b2 的所有组合来执行此操作,并在 b3 和 b1、b2 之间建立关系,如果 b3.property/b1.property>x 和 b3.property/b2.property>x .但随后对所有组合执行该操作将是一个笛卡尔积
    • 你应该在你的问题中说清楚。可能可以删除笛卡尔积,但需要付出很大的努力来修改现有答案。将不得不看看我是否有额外的时间。
    • 有没有其他方法可以为这个图建模来解决问题?问题是图中所有的B节点都是唯一的实体,所以不知道没有笛卡尔积是否可以解决
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 2021-10-20
    • 2019-04-10
    • 2011-05-04
    • 1970-01-01
    相关资源
    最近更新 更多