[英]Neo4j: Cypher Query With Variable Length and Condition on Node Labels
With variable length relationships (see here in the neo4j manual ), it is possible to have a variable number of relationships with a certain label between two nodes. 使用可变长度关系 (请参见neo4j手册中的此处 ),可以在两个节点之间具有一定数量的具有一定标签的关系。
# Cypher
match (g1:Group)-[:sub_group*]->(g2:Group) return g1, g2
I'm looking for the same thing with nodes , ie a way to query for two nodes with a variable number of nodes in between , but with a label condition on the nodes rather than the relationships : 我在寻找与节点相同的东西 ,即一种查询两个节点的方法,两个节点之间的节点数目可变 ,但是节点上的标签条件而不是关系 :
# Looking for something like this in Cypher:
match (g1:Group)-->(:Group*)-->(g2:Group) return g1, g2
I would use this mechanism, for example, to find all (direct or indirect) members of a group within a group structure. 我将使用这种机制,例如,在组结构中查找组的所有(直接或间接)成员。
# Looking for somthing like this in Cypher:
match (group:Group)-->(:Group*)-->(member:User) return member
Take, for example, this structure: 以以下结构为例:
group1:Group
|-------> group2:Group -------> user1:User
|-------> group3:Group
|--------> page1:Page -----> group4:Group -----> user2:User
In this example, user1
is a member of group1
and group2
, but user2
is only member of group4
, not member of the other groups, because a non- Group
labeled node is in between. 在这个例子中,
user1
是其成员的group1
和group2
,但user2
只是构件group4
,其它组不是会员,因为非Group
标记的节点是介于两者之间。
A more abstract pattern would be a kind of repeat operator |...|*
in Cypher: 在Cypher中,更抽象的模式是一种重复运算符
|...|*
:
# Looking for repeat operator in Cypher:
match (g1:Group)|-[:is_subgroup_of]->(:Group)|*-[:is_member_of]->(member:User)
return member
Does anyone know of such a repeat operator? 有人知道这样的重复运算符吗? Thanks!
谢谢!
One solution I've found, is to use a condition on the nodes using where
, but I hope, there is a better (and shorter) soluation out there! 我发现的一种解决方案是在使用
where
的节点上使用条件,但我希望那里有更好(或更短)的解决方案!
# Cypher
match path = (member:User)<-[*]-(g:Group{id:1})
where all(node in tail(nodes(path)) where ('Group' in labels(node)))
return member
In the above query, all(node in tail(nodes(path)) where ('Group' in labels(node)))
is one single where condition, which consists of the following key parts: 在上述查询中,
all(node in tail(nodes(path)) where ('Group' in labels(node)))
是一个单where条件,它由以下关键部分组成:
all
: ALL(x in coll where pred)
: TRUE if pred
is TRUE for all values in coll
all
: ALL(x in coll where pred)
:如果coll
所有值的pred
为TRUE则为TRUE nodes(path)
: NODES(path)
: Returns the nodes in path
nodes(path)
: NODES(path)
:返回节点path
tail()
: TAIL(coll)
: coll
except first element–––I'm using this, because the first node is a User
, not a Group
. tail()
: TAIL(coll)
:除第一个元素外的coll
–我正在使用它,因为第一个节点是User
,而不是Group
。 How about this: 这个怎么样:
MATCH (:Group {id:1})<-[:IS_SUBGROUP_OF|:IS_MEMBER_OF*]-(u:User)
RETURN DISTINCT u
This will: 这将:
I know this relies on relationships types rather than node labels, but IMHO this is a more graphy approach. 我知道这依赖于关系类型而不是节点标签,但是恕我直言,这是一种更加图形化的方法。
Let me know if this would work or not. 让我知道这是否行得通。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.