如何基于顶点ID用Gremlin双向遍历查询祖先与后代
解决方案:Gremlin 双向无限制深度遍历查询
针对你提出的三个问题,以下是完整的Gremlin查询方案,同时满足双向遍历、无限制深度、返回指定属性的需求:
核心查询语句(结构化输出)
g.V('{目标ID}') // 同时遍历后代与祖先分支 .union( // 遍历所有后代(isParentOf关系),输出结构化数据 repeat(out('isParentOf')).emit().project('relation', 'id', 'name') .by(constant('isParentOf')) .by(id()) .by('name'), // 遍历所有祖先(isChildOf关系),输出结构化数据 repeat(out('isChildOf')).emit().project('relation', 'id', 'name') .by(constant('isChildOf')) .by(id()) .by('name') ) // 按关系类型分组,保留遍历顺序 .group() .by('relation') .by(select('id', 'name').fold())
关键部分说明
- 双向遍历实现:使用
union()同时执行两个遍历分支,分别处理isParentOf(后代)和isChildOf(祖先)关系。 - 无限制深度遍历:
repeat(...).emit()会循环遍历直到没有后续节点,自动终止于叶子/根节点,无需指定times()参数限制深度。 - 属性输出:
project()将每个节点的关系类型、ID、name属性整理成结构化对象,替代单纯的顶点引用。 - 结果分组:
group()按关系类型分类,fold()保留遍历顺序(从近到远,符合示例要求)。
匹配示例格式的查询(字符串化输出)
如果需要完全匹配示例中的22(Person2)格式,可调整为:
g.V('{目标ID}') .union( repeat(out('isParentOf')).emit().project('relation', 'info') .by(constant('isParentOf')) .by(select(id(), 'name').map(select(0).concat('(').concat(select(1).capitalize()).concat(')'))), repeat(out('isChildOf')).emit().project('relation', 'info') .by(constant('isChildOf')) .by(select(id(), 'name').map(select(0).concat('(').concat(select(1).capitalize()).concat(')'))) ) .group() .by('relation') .by(select('info').fold())
示例验证
- 查询Person1(id=11):仅返回
isParentOf分支结果:{ "isParentOf": ["22(Person2)", "33(Person3)", "44(Person4)", "55(Person5)"] } - 查询Person3(id=33):同时返回祖先与后代:
{ "isParentOf": ["44(Person4)", "55(Person5)"], "isChildOf": ["22(Person2)", "11(Person1)"] } - 查询Person5(id=55):仅返回
isChildOf分支结果:{ "isChildOf": ["44(Person4)", "33(Person3)", "22(Person2)", "11(Person1)"] }
内容的提问来源于stack exchange,提问作者Gurpreet Singh
相关产品推荐
相关产品推荐

