Neo4j:节点标签上具有可变长度和条件的Cypher查询

时间:2015-04-20 18:41:16

标签: neo4j cypher

我正在寻找什么

使用可变长度关系(参见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

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

2 个答案:

答案 0 :(得分: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)))是一个条件,其中包含以下关键部分:

  • allALL(x in coll where pred):如果所有值的pred为TRUE,则为TRUE coll
  • nodes(path)NODES(path):返回path
  • 中的节点
  • tail()TAIL(coll)coll除了第一个元素---我正在使用它,因为第一个节点是User,而不是{{1} }。

参考

答案 1 :(得分:1)

这个怎么样:

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关系的节点
  • 并丢弃重复的结果(属于树中多个组的用户会多次出现)

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

请告诉我这是否有效。