Cypher:如何导航图形以找到正确的路径
Cypher: how to navigate graph to find the right path
我是 Cypher 的新手,我正在尝试学习正确导航图表。
我有这样的情况:2 个用户关联了相同的服务,该服务可通过帐户访问。因此,用户 'usr01' 可以使用帐户 'acct01' 访问服务 'srv01';用户 'usr02 可以使用帐户 'acct02' 访问服务 'srv01'。
目的是像这样提取2条记录:
usr01 - srv01 - acct01
usr02 - srv01 - acct02
所以,我执行了这些查询:
创建节点:
create (s:XService {serviceId:'srv01'}) return s;
create (u:XUser {userId:'usr01'}) return u;
create (u:XUser {userId:'usr02'}) return u;
create (u:XAccount {accountId:'acct01'}) return u;
create (u:XAccount {accountId:'acct02'}) return u;
建立关系:
MATCH (u:XUser{userId:'usr01'}), (s:XService {serviceId:'srv01'}), (a:XAccount {accountId:'acct01'})
CREATE (u)-[:HAS_SERVICE]->(s)-[:HAS_ACCOUNT]->(a)
MATCH (u:XUser{userId:'usr02'}), (s:XService {serviceId:'srv01'}), (a:XAccount {accountId:'acct02'})
CREATE (u)-[:HAS_SERVICE]->(s)-[:HAS_ACCOUNT]->(a)
我收到的图表结果是this
如果我执行此查询 - 从用户 usr01 开始:
MATCH (u:XUser {userId: 'usr01'}) OPTIONAL MATCH (u)-[:HAS_SERVICE]->(s:XService) OPTIONAL MATCH (s)-[:HAS_ACCOUNT]->(a:XAccount)
RETURN u.userId, s.serviceId, a.accountId;
我得到this结果:
那么,我怎样才能获得上述结果 (usr01 - srv01 - acct01) 而不是我收到的笛卡尔积?
提前致谢
问题在于,当您添加服务与帐户之间的关系时,您并未指明与用户的关联关系。作为解决方案,您可以制作一个智能节点 "Access Rule":
MERGE (s:XService {serviceId:'srv01'})
MERGE (u1:XUser {userId:'usr01'})
MERGE (ua1:XAccount {accountId:'acct01'})
MERGE (u1)-[:can_access]->(ca1:AccessRule)-[:to_service]->(s)
MERGE (ca1)-[:with_account]->(ua1)
MERGE (u2:XUser {userId:'usr02'})
MERGE (ua2:XAccount {accountId:'acct02'})
MERGE (u2)-[:can_access]->(ca2:AccessRule)-[:to_service]->(s)
MERGE (ca2)-[:with_account]->(ua2)
还有一个查询:
MATCH (u:XUser {userId: 'usr01'})
OPTIONAL MATCH ps = (u)-[:can_access]->(ca1:AccessRule)-[:to_service]->(s:XService)
OPTIONAL MATCH pa = (ca1)-[:with_account]->(a:XAccount)
RETURN u, ps, pa
我是 Cypher 的新手,我正在尝试学习正确导航图表。 我有这样的情况:2 个用户关联了相同的服务,该服务可通过帐户访问。因此,用户 'usr01' 可以使用帐户 'acct01' 访问服务 'srv01';用户 'usr02 可以使用帐户 'acct02' 访问服务 'srv01'。 目的是像这样提取2条记录:
usr01 - srv01 - acct01
usr02 - srv01 - acct02
所以,我执行了这些查询:
创建节点:
create (s:XService {serviceId:'srv01'}) return s; create (u:XUser {userId:'usr01'}) return u; create (u:XUser {userId:'usr02'}) return u; create (u:XAccount {accountId:'acct01'}) return u; create (u:XAccount {accountId:'acct02'}) return u;
建立关系:
MATCH (u:XUser{userId:'usr01'}), (s:XService {serviceId:'srv01'}), (a:XAccount {accountId:'acct01'}) CREATE (u)-[:HAS_SERVICE]->(s)-[:HAS_ACCOUNT]->(a) MATCH (u:XUser{userId:'usr02'}), (s:XService {serviceId:'srv01'}), (a:XAccount {accountId:'acct02'}) CREATE (u)-[:HAS_SERVICE]->(s)-[:HAS_ACCOUNT]->(a)
我收到的图表结果是this
如果我执行此查询 - 从用户 usr01 开始:
MATCH (u:XUser {userId: 'usr01'}) OPTIONAL MATCH (u)-[:HAS_SERVICE]->(s:XService) OPTIONAL MATCH (s)-[:HAS_ACCOUNT]->(a:XAccount)
RETURN u.userId, s.serviceId, a.accountId;
我得到this结果:
那么,我怎样才能获得上述结果 (usr01 - srv01 - acct01) 而不是我收到的笛卡尔积? 提前致谢
问题在于,当您添加服务与帐户之间的关系时,您并未指明与用户的关联关系。作为解决方案,您可以制作一个智能节点 "Access Rule":
MERGE (s:XService {serviceId:'srv01'})
MERGE (u1:XUser {userId:'usr01'})
MERGE (ua1:XAccount {accountId:'acct01'})
MERGE (u1)-[:can_access]->(ca1:AccessRule)-[:to_service]->(s)
MERGE (ca1)-[:with_account]->(ua1)
MERGE (u2:XUser {userId:'usr02'})
MERGE (ua2:XAccount {accountId:'acct02'})
MERGE (u2)-[:can_access]->(ca2:AccessRule)-[:to_service]->(s)
MERGE (ca2)-[:with_account]->(ua2)
还有一个查询:
MATCH (u:XUser {userId: 'usr01'})
OPTIONAL MATCH ps = (u)-[:can_access]->(ca1:AccessRule)-[:to_service]->(s:XService)
OPTIONAL MATCH pa = (ca1)-[:with_account]->(a:XAccount)
RETURN u, ps, pa