Apache TinkerPop Gremlin中是否存在类似SQL左连接的实现方式?
解决方案
你遇到的问题本质是repeat()步骤在无匹配边时会自动过滤上游数据,Gremlin中对应SQL左连接的核心实现是optional()步骤,它会保留上游数据,内部遍历无结果时返回空值。
调整后的查询语句
g.V().hasLabel('person').as('person') // 获取用户直接管理的权限节点 .out('administers').as('explicit_admin_role') // optional实现左连接:无下级权限时也保留上游用户+直接权限数据 .optional( repeat(out('owns').as('implicit_admin_role')).emit() ) // 构造返回结果 .project('person_name', 'explicit_admin_role', 'implicit_admin_role') .by(select('person').values('name')) .by(select('explicit_admin_role').values('name')) .by(coalesce(select('implicit_admin_role').values('name'), constant(null)))
如果你的需求是把直接管理的权限节点也纳入可访问权限列表(即隐式权限包含自身),可以调整optional内部逻辑如下:
.optional( union( identity().as('implicit_admin_role'), repeat(out('owns').as('implicit_admin_role')).emit() ) )
关键逻辑说明
optional():完全等价SQL左连接效果,内部遍历匹配到结果就返回,匹配不到也不会丢弃上游已经获取的用户、直接权限节点数据coalesce():处理空值场景,没有下级权限时implicit_admin_role字段返回null- 替换多次
select为project构造结果,代码可读性更高,也避免多次遍历取数的性能损耗
针对你提供的测试数据,调整后的查询会正确返回mike管理My Office UK的记录,不会再遗漏底层权限节点的管理员数据。
内容的提问来源于stack exchange,提问作者Matthew Darwin
相关产品推荐
相关产品推荐

