为什么这两个会产生不同的结果?
graph.traversal()
.V().map(__.out("contains"))
.valueMap(true).next(100)
相比
graph.traversal()
.V().out("contains")
.valueMap(true).next(100)
为什么我更喜欢 map 而不是直接调用 .out() 方法?通过这种方式,我可以组织我的代码,在那里我可以从方法和“映射”到现有遍历的遍历。
为什么这两个会产生不同的结果?
graph.traversal()
.V().map(__.out("contains"))
.valueMap(true).next(100)
相比
graph.traversal()
.V().out("contains")
.valueMap(true).next(100)
为什么我更喜欢 map 而不是直接调用 .out() 方法?通过这种方式,我可以组织我的代码,在那里我可以从方法和“映射”到现有遍历的遍历。
在考虑这个问题时,回想一下 Gremlin 有点像一个处理管道,其中对象被拉过管道中的每个步骤以应用一些转换、过滤器等。因此,以最简单的形式给出您的示例,您会说您正在获取所有顶点并在out()
边上遍历,这意味着您正在比较以下遍历和结果:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().out()
==>v[3]
==>v[2]
==>v[4]
==>v[5]
==>v[3]
==>v[3]
gremlin> g.V().map(out())
==>v[3]
==>v[5]
==>v[3]
这些遍历返回两个不同的结果,因为您向 Gremlin 询问两个不同的东西。在第一种情况下,out()
不是 的形式map()
,它是 的形式flatMap()
,意味着对于通过管道的每个顶点遍历器,它将迭代所有出边并遍历并返回相邻顶点(即一对多变换)。在第二种情况下,您要求 Gremlin 对map()
另一个对象进行简单的顶点转换(即一对一变换),在这种情况下,这将是out()
该遍历器流中的第一个对象的结果。
为了证明您可以简单地更改map()
为flatMap()
如下:
gremlin> g.V().flatMap(out())
==>v[3]
==>v[2]
==>v[4]
==>v[5]
==>v[3]
==>v[3]
或者fold()
将结果out()
保存到单个对象以保持一对一的转换逻辑:
gremlin> g.V().map(out().fold())
==>[v[3],v[2],v[4]]
==>[]
==>[]
==>[v[5],v[3]]
==>[]
==>[v[3]]