Neo4j层级空间用户可见性Cypher查询修正需求
修正Cypher查询以获取用户可见的最高层级空间列表
问题场景
我们有用户与空间的层级关联结构,需要查询用户可见的空间列表,要求:
- 若用户同时是某个空间及其子空间的成员,仅返回层级最高的那个空间(比如Simon DDD同时是「TOP LEVEL SPACE」和「LEVEL 2 SPACE」成员,只返回前者)
- 若用户仅为某个非顶级空间的成员,返回该空间(比如Simon LALALA仅为「LEVEL 2 SPACE」成员,返回该空间)
- 用户仅为顶级空间成员时,正常返回该顶级空间
现有Cypher查询无法满足第一个要求,会同时返回用户关联的所有符合状态的空间,需要修正。
现有查询语句
MATCH (user:User {auth_token: $auth_token}) MATCH (space:Space) WHERE ( (NOT (space)<-[:PARENT_OF]-(:Space) AND (user)-[:MEMBER_OF]->(space) AND space.pod_state IN ['active', 'pending'] AND space.pod_type IN ['standard', 'readonly']) OR (EXISTS {MATCH (parent:Space)-[:PARENT_OF*]->(space)<-[:MEMBER_OF]-(user) WHERE NOT (user)-[:MEMBER_OF]->(parent) AND space.pod_state IN ['active', 'pending'] AND space.pod_type IN ['standard', 'readonly']}) ) RETURN space
修正后的查询语句
MATCH (user:User {auth_token: $auth_token})-[:MEMBER_OF]->(space:Space) WHERE space.pod_state IN ['active', 'pending'] AND space.pod_type IN ['standard', 'readonly'] AND NOT EXISTS { MATCH (user)-[:MEMBER_OF]->(ancestor:Space)-[:PARENT_OF*]->(space) } RETURN space
逻辑说明
- 首先匹配用户直接关联的所有符合状态、类型要求的空间
- 然后过滤掉那些存在用户同时也是其祖先空间成员的空间——也就是说,只保留用户关联的空间中,没有更高层级的祖先空间是用户成员的那些,这些就是用户可见的最高层级空间
这样既满足了Simon DDD只返回顶级空间的需求,也保留了Simon LALALA返回其唯一关联的非顶级空间的逻辑,同时对仅关联顶级空间的用户也能正常返回结果。
内容的提问来源于stack exchange,提问作者Makarov
相关产品推荐
相关产品推荐

