【问题标题】:Matching intersections/combinations in cypher匹配密码中的交叉点/组合
【发布时间】:2018-06-28 13:14:36
【问题描述】:

我有一个图表,其中绿色节点可能链接到一个或多个红色节点,然后链接到一组蓝色节点。红色节点也有一个 amt 属性,它指示集合中蓝色节点的最小数量,需要匹配才能“满足”红色节点。如果一组给定的蓝色节点满足绿色节点的所有红色邻居,则该组“有资格”成为绿色节点。

例子

如何编写一个密码查询来返回一组给定蓝色节点的所有合格绿色节点?

如果其红色邻居的所有蓝色节点都匹配,我想出了以下返回绿色节点。但是,我不需要匹配所有,而是为每个红色节点指定的 amt。

MATCH (g:Green)-->(r:Red)-->(b:Blue)
WITH g, COLLECT(b.name) AS myset
WHERE ALL(n in myset where n in ["1", "2", "3", "4", "8", "9", "11"])
RETURN p

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    首先你需要找到所有的绿色候选,然后通过红色节点检查它们:

    WITH ["1", "2", "3", "4", "8", "9", "11"] AS blues
    MATCH (g:Green)-[:requires]->(r:Red)-[:contains]->(b:Blue) WHERE b.name IN blues
    
    WITH distinct g, blues
    MATCH (g)-[:requires]->(r:Red)
    OPTIONAL MATCH (r)-[:contains]->(b:Blue) WHERE b.name IN blues
    
    WITH g, r, size(collect(DISTINCT b)) AS bCount
    WITH g, collect([r.amt, bCount]) AS test
    WITH g WHERe all(t IN test WHERE t[0] <= t[1])
    RETURN g
    

    【讨论】:

    • 请注意,收集蓝色节点可能会更好一些,然后在 OPTIONAL MATCH 中对节点本身使用 IN 检查,而不是使用 b.name 执行此操作。它将不必进行财产访问。
    • @InverseFalcon 是的,你是对的 - 如果需要,还有一些东西需要优化))
    • 我刚刚意识到,bCount 计算连接到红色节点的蓝色节点并将其与红色 node.amt 进行比较,但是需要的是 bCount 应该是红色节点与输入共有的蓝色节点的数量.例如,如果 r1 连接到 [1, 2, 3] r1.amt 是 2 并且 r2 连接到 [2, 4],r2.amt =1 那么输入 [1, 2, 4] 那么两个红色音符都是满足,因为 r1 至少有 2 个与输入相同的节点 (r1.amt),而 r2 至少有 1 个与输入相同的节点 (r2.amt)。
    【解决方案2】:

    此查询应返回 Green 节点,其“必需”Red 节点所有至少具有各自需要的 amt 或“包含”Blue 节点:

    MATCH (g:Green)-[:requires]->(r:Red)
    WITH g, r, SIZE((r)-[:contains]->(:Blue)) AS cnt
    WITH g, COLLECT({r: r, cnt: cnt}) AS data
    WHERE ALL(d IN data WHERE d.cnt >= d.r.amt)
    RETURN g;
    

    【讨论】:

    • 但是如何输入?查询应采用蓝色节点的集合,并从给定集合中的蓝色节点中返回满足其要求的所有绿色节点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多