【问题标题】:Neo4j: Cypher Query With Variable Length and Condition on Node LabelsNeo4j:节点标签上具有可变长度和条件的 Cypher 查询
【发布时间】:2015-06-27 15:35:40
【问题描述】:

我在寻找什么

使用可变长度关系(请参阅here in the neo4j manual),可以在两个节点之间建立具有特定标签的可变数量的关系。

# Cypher
match (g1:Group)-[:sub_group*]->(g2:Group) return g1, g2

正在寻找与节点相同的东西,即一种查询两个节点之间的节点数量可变的方法,但使用 >在节点而不是关系上标记条件

# Looking for something like this in Cypher:
match (g1:Group)-->(:Group*)-->(g2:Group) return g1, g2

示例

我会使用这种机制,例如,在组结构中查找组的所有(直接或间接)成员。

# Looking for somthing like this in Cypher:
match (group:Group)-->(:Group*)-->(member:User) return member

以这个结构为例:

group1:Group
   |-------> group2:Group -------> user1:User
   |-------> group3:Group
                  |--------> page1:Page -----> group4:Group -----> user2:User

在此示例中,user1group1group2 的成员,但 user2 只是 group4 的成员,而不是其他组的成员,因为非Group 标记的节点介于两者之间。

抽象

更抽象的模式是 Cypher 中的一种重复运算符 |...|*

# Looking for repeat operator in Cypher:
match (g1:Group)|-[:is_subgroup_of]->(:Group)|*-[:is_member_of]->(member:User) 
return member

有人知道这样的重复运算符吗?谢谢!

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    可能的解决方案

    我找到的一个解决方案是使用where 在节点上使用条件,但我希望有更好(更短)的解决方案!

    # Cypher
    match path = (member:User)<-[*]-(g:Group{id:1}) 
    where all(node in tail(nodes(path)) where ('Group' in labels(node))) 
    return member
    

    说明

    在上述查询中,all(node in tail(nodes(path)) where ('Group' in labels(node))) 是一个单独的 where 条件,由以下几个关键部分组成:

    • all: ALL(x in coll where pred): TRUE 如果pred 对所有值都为 TRUE coll
    • nodes(path):NODES(path):返回path中的节点
    • tail():TAIL(coll):coll 除了第一个元素——我正在使用这个,因为第一个节点是User,而不是Group

    参考

    【讨论】:

      【解决方案2】:

      这个怎么样:

      MATCH (:Group {id:1})<-[:IS_SUBGROUP_OF|:IS_MEMBER_OF*]-(u:User)
      RETURN DISTINCT u
      

      这将:

      • 查找 ID 为 1 的组的所有子树
      • 仅在传入方向遍历关系 IS_GROUP_OF 和 IS_MEMBER_OF(表示属于具有 ID 的组或其子组之一的子组或用户)
      • 仅返回与子树中的组具有 IS_MEMBER_OF 关系的节点
      • 并丢弃重复的结果(属于树中多个组的用户会出现多次)

      我知道这依赖于关系类型而不是节点标签,但恕我直言,这是一种更图形的方法。

      让我知道这是否可行。

      【讨论】:

      • 是的,这是我的“后备方法”。但我不喜欢其中的冗余:我已经告诉节点它们的类型(标签)::User:Group 等等。现在,将相同的信息也输入到关系中(:is_member_of 用于用户,:is_subgroup_of 用于组)感觉是多余的。 --- 但是,最终,如果它更快,我可能会这样做。
      • 我不认为有任何冗余。在我的示例查询中,标签仅用于路径的开始和结束节点,而不是它们之间的节点。您需要定义感兴趣的路径。我的方法是使用关系类型来做到这一点,而你的方法是通过过滤中间节点的标签来做到这一点。
      猜你喜欢
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多