【问题标题】:Not able to manipulate paths collection in neo4j cypher无法在 neo4j 密码中操作路径集合
【发布时间】:2016-01-12 16:53:18
【问题描述】:

仍在努力获取正确的查询。下图大多是单向的,代表谁喜欢谁。但具有“朋友”关系的人会特别关注与谁成为终极朋友。

    create (jacob {short:"Jacob",level:"start"})
        ,(leena{short:"Leena"})
        ,(bob{short:"Bob",level:"end"})
        ,(brad{short:"Brad",level:"end"})
        ,(jacob)-[:LIKES]->(leena)
        ,(leena)-[:LIKES]->(bob)
        ,(leena)-[:LIKES]->(brad)
        ,(jacob)-[:FRIENDS]->(brad)
        ,(kyle{short:"Kyle",level:"start"})
        ,(rick{short:"Rick"})
        ,(kyle)-[:LIKES]->(leena)
        ,(kyle)-[:LIKES]->(rick)
        ,(rick)-[:LIKES]->(brad);

结束“喜欢”的所有来源均由

给出
match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
return distinct extract(m in nodes(p) | m.short);

[Jacob, Leena, Bob]
[Jacob, Leena, Brad]
[Kyle, Rick, Brad]
[Kyle, Leena, Bob]
[Kyle, Leena, Brad]

但是对于布拉德来说,喜欢应该来自他的朋友。在图中,对于 Brad,只有 Jacob 是他的 FRIEND。因此,应该从输出中排除来自 Kyle 的最终点赞。

我试图实现的逻辑是获取不必要的路径并将它们从上面的输出中排除。 以下查询给出的不必要的路径。 where 子句很简单,因为 FRIENDship 总是在 2 之间找到,然后很容易收集集合中的第一个和最后一个节点。

match q=()-[:FRIENDS*1]->()
with collect(nodes(q)[0]) as y,collect(nodes(q)[1]) as z
match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    where any(x in nodes(p) where x in z) and not any(x in nodes(p) where x in y)
return distinct extract(m in nodes(p) | m.short);

[Kyle, Rick, Brad]
[Kyle, Leena, Brad]

然后排除

match q=()-[:FRIENDS*1]->()
with collect(nodes(q)[0]) as y,collect(nodes(q)[1]) as z
match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    where any(x in nodes(p) where x in z) and not any(x in nodes(p) where x in y)
match r=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    where not all(node2 in nodes(p) where node2 in nodes(r))
return distinct extract(m in nodes(r) | m.short);

我仍然得到所有路径,包括不必要的路径。在cypher中可以比较完整的集合吗?在上述查询中,not all(.. 不起作用。

为了使图形通用,开始和结束节点可以存在于它们之间,即在结束节点之外和开始之前可以有节点。

【问题讨论】:

    标签: collections path neo4j cypher


    【解决方案1】:

    如果第一个查询返回完整的 LIKES 路径集,第二个查询返回要排除的 LIKES 路径集,此查询是否为您提供下一个您正在寻找的结果?

    它将每个集合收集到一个要保留的集合和一个不相关的集合中,然后只返回不在不相关集合中的保留集合中的集合。

    match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    with collect(nodes(p)) as full_set
    match q=()-[:FRIENDS*1]->()
    with full_set, collect(nodes(q)[0]) as y,collect(nodes(q)[1]) as z
    match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    where any(x in nodes(p) where x in z) and not any(x in nodes(p) where x in y)
    with full_set, collect(nodes(p)) as irrelevent_set
    with filter (keep in full_set where not keep in irrelevent_set) as keep_sets
    unwind keep_sets as keep
    return extract(person in keep | person.short)
    

    编辑以改为返回路径:

    match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    with collect(p) as full_set
    match q=()-[:FRIENDS*1]->()
    with full_set, collect(nodes(q)[0]) as y,collect(nodes(q)[1]) as z
    match p=({level:'start'})-[:LIKES*1..6]->({level:'end'})
    where any(x in nodes(p) where x in z) and not any(x in nodes(p) where x in y)
    with full_set, collect(p) as irrelevent_set
    with filter (keep in full_set where not keep in irrelevent_set) as keep_sets
    unwind keep_sets as keep
    return keep
    

    【讨论】:

    • 谢谢戴夫。输出是正确的,但它是节点的集合。我在查询中尝试的是输出会导致节点和关系的路径。现在在 json 输出中,关系字段是空数组。
    • 添加和修改了一点match p=({level:'start'})-[:LIKES*1..6]->({level:'end'}) where all(k in nodes(p) where k in keep)
    • 哦,太好了。我从没想过 cypher 可以建立路径集合。惊人的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多