Gremlin查询:如何不遍历关联顶点获取顶点属性与边元数据
问题原因
原有查询会触发Grant顶点遍历,核心问题出在inV().id()这一步:
- 只要调用了
inV()步骤,绝大多数图数据库实现都会触发邻接顶点的存储读取逻辑,哪怕后续只取顶点ID,也会把完整的Grant顶点对象加载到遍历内存里,产生不必要的高开销。 - 实际上
hasGrant边本身就存储了需要的所有数据:边关联的入端(Grant顶点)ID、边自带的Type属性,根本不需要遍历到Grant顶点就能拿到全部目标字段。
正确实现
用TinkerPop官方提供的inVertexId()步骤替代inV().id()即可,这个步骤会直接从已加载的边对象上读取入顶点ID,完全不会触发邻接顶点的存储访问,性能开销极低。
完整查询代码如下:
g.V().hasLabel('Permission').has('name', 'Column_Commit') .project('PermissionId', 'GrantInfo') .by('permissionId') .by( outE("hasGrant") .project('GrantId', 'Type') .by(inVertexId()) .by('Type') .fold() )
补充说明
- 上述查询返回结果中,每个元素对应一个匹配的Permission顶点,
PermissionId字段为权限ID,GrantInfo是数组结构,每个元素包含关联的授权IDGrantId和边的授权类型Type。 - 全程仅读取Permission顶点和
hasGrant边的数据,没有任何访问Grant顶点存储的操作,完全满足性能优化要求。 - 注意边属性名是首字母大写的
Type,不要误写为小写type避免取值失败。 - 如果使用的是较老版本的TinkerPop实现,不支持
inVertexId()步骤,可以替换为by(__.values(org.apache.tinkerpop.gremlin.structure.Edge.ToId)),效果完全一致,同样不会触发顶点遍历。
内容的提问来源于stack exchange,提问作者macpak
相关产品推荐
相关产品推荐

