简体   繁体   English

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

[英]Neo4j: Cypher Query With Variable Length and Condition on Node Labels

What I'm looking for 我在寻找什么

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

Example

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是其成员的group1group2 ,但user2只是构件group4 ,其它组不是会员,因为非Group标记的节点是介于两者之间。

Abstraction 抽象化

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! 谢谢!

Possible Solution 可能的解决方案

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

Explanation 说明

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 allALL(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

Reference 参考

How about this: 这个怎么样:

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

This will: 这将:

  • find all subtrees of the group with ID 1 查找ID为1的组的所有子树
  • only traverse the relationships IS_GROUP_OF and IS_MEMBER_OF in incoming direction (meaning sub-groups or users that belong to group with ID or one of its sub-groups) 仅沿传入方向遍历关系IS_GROUP_OF和IS_MEMBER_OF(表示属于具有ID或其子组之一的组的子组或用户)
  • only return nodes which have a IS_MEMBER_OF relationship to a group in the subtree 仅返回与子树中的组具有IS_MEMBER_OF关系的节点
  • and discard duplicate results (users who belong to more than one of the groups in the tree would otherwise appear multiple times) 并丢弃重复的结果(属于树中多个组之一的用户将多次出现)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM