TinkerPop多顶点类型多层查询问题求助
解决Gremlin中Union合并多类型多跳查询的问题
我明白你的需求了——要把Marko的直接好友(1跳的person类型顶点)和他第二跳的software类型顶点这两部分结果合并起来对吧?之前你对union的用法有点误解,我来帮你纠正并给出正确的写法。
先拆解你的两个核心查询(简化版)
首先,我们可以把你之前的两个查询简化一下,因为repeat(both()).times(1)其实等价于直接用both(),不需要repeat;而且emit在这里也没必要,因为我们只需要指定跳数的结果,不是路径上的所有节点:
- 获取Marko的直接好友(1跳person)
g.V(1).hasLabel("person").both().hasLabel("person").values("name")
- 获取Marko第二跳的software顶点
这里两种写法都可以,选你觉得直观的:
// 写法1:直接两次both()代表2跳 g.V(1).hasLabel("person").both().both().hasLabel("software").values("name") // 写法2:用repeat明确指定跳数 g.V(1).hasLabel("person").repeat(both()).times(2).hasLabel("software").values("name")
用Union正确合并两个查询
Union的核心是把多个独立的遍历逻辑作为参数传入union()中,而不是像你之前那样空调用或者传入单个顶点。正确的合并写法如下:
写法1:合并后直接输出名称
g.V(1).hasLabel("person").union( // 分支1:直接好友 both().hasLabel("person").values("name"), // 分支2:第二跳软件 repeat(both()).times(2).hasLabel("software").values("name") )
写法2:先合并顶点,再统一输出名称(更简洁)
如果需要保留顶点对象后续操作,或者只是想统一处理输出,也可以这样写:
g.V(1).hasLabel("person").union( both().hasLabel("person"), repeat(both()).times(2).hasLabel("software") ).values("name")
纠正你之前的错误写法
你之前尝试的这两种写法都不符合Union的语法:
g.V(1).union().V(2):union()必须传入至少一个遍历器作为参数,空调用是无效的g.V(1).union(V(2)):V(2)是一个独立的顶点查询,不是从V(1)出发的遍历分支,Union需要的是基于同一个起始点的不同遍历逻辑,或者独立的遍历流
额外补充:去重(如果需要)
虽然你的场景中person和software类型不同,不会有重复结果,但如果后续有同类顶点可能重叠的情况,可以在Union后加上dedup()去重:
g.V(1).hasLabel("person").union( both().hasLabel("person"), repeat(both()).times(2).hasLabel("software") ).dedup().values("name")
内容的提问来源于stack exchange,提问作者Srinath Ganesh
相关产品推荐
相关产品推荐

