如何收集 TinkerPop3 中的可选分支?
How to collect optional branches in TinkerPop3?
我有一个看起来像这样的图表:
使用 gremlin-scala,我试图从 A 遍历并收集这些元组:
(A, Some(A1)), (B, None), (C, Some(A2))
所以本质上我想重复地从边缘取出 α
并选择性地分支到 β
,收集这些边缘。我猜我需要注入一个空的 "step" 如果没有 β
边缘,但我还不知道该怎么做。
现在 jump
已被神秘移除(TP 3.1+)
,我也对遍历 β
后如何倒带感到有点困惑
到目前为止我有类似的东西:
graph.V("A").untilWithTraverser(t => t.get.outE(α).notExists()
).repeat(_.out(α).as(foo).out(β).as(bar)).select((foo,bar)).toList
但是如果 "trunk" 上的任何节点缺少 β
出边
,这不会倒回到主要遍历并且失败
我无法提供 gremlin-scala 解决方案,但您可以轻松转换以下 Groovy 示例:
g.V("A").until(__.not(outE("alpha"))).
repeat(out("alpha")).path().by(union(identity(), out("beta")).fold())
这将 return:
[[A, A1], [B], [C, A2]]
海事组织这就足够了。但是,如果您需要一组一致的 2 个条目,您可以这样做:
g.V("A").until(__.not(outE("alpha"))).repeat(out("alpha")).
path().by(union(identity(), coalesce(out("beta"), constant("N/A"))).fold())
...然后 return:
[[A, A1], [B, N/A], [C, A2]]
完成会话:
这是我的 gremlin-scala 解决方案,基于 Daniel 的回答。
val unionTraversal = __[(String, Vertex)].union(
__[Vertex].identity.map("blob" -> _),
__.out(Beta).map("beta" -> _)
).traversal
def pathTuplesToScalaTuples(path: Path) =
path.objects.asScala.map(_.asInstanceOf[java.util.ArrayList[(String, Vertex)]].asScala.toList).toList
val pathO = graph.V("A")
.until(_.not(_.out(Alpha)))
.repeat(_.out(Alpha))
.path.by(unionTraversal.fold).headOption
val tuples = pathO.map(pathTuplesToScalaTuples)
不幸的是,这涉及到一些实际使发出的顶点有用的问题。
首先,当将匿名遍历传递到联合时,步骤标签会被删除,因此您不能使用 .as("blob")
标记发出的集合——这就是将它们包装在带有字符串标签的元组中的解决方法对于.
其次,gremlin-scala 还没有 Path
的包装器(并且可能永远不会得到它,因为路径可以有任意结构)所以我们必须做一个丑陋的转换。
我有一个看起来像这样的图表:
使用 gremlin-scala,我试图从 A 遍历并收集这些元组:
(A, Some(A1)), (B, None), (C, Some(A2))
所以本质上我想重复地从边缘取出 α
并选择性地分支到 β
,收集这些边缘。我猜我需要注入一个空的 "step" 如果没有 β
边缘,但我还不知道该怎么做。
现在 jump
已被神秘移除(TP 3.1+)
β
后如何倒带感到有点困惑
到目前为止我有类似的东西:
graph.V("A").untilWithTraverser(t => t.get.outE(α).notExists()
).repeat(_.out(α).as(foo).out(β).as(bar)).select((foo,bar)).toList
但是如果 "trunk" 上的任何节点缺少 β
出边
我无法提供 gremlin-scala 解决方案,但您可以轻松转换以下 Groovy 示例:
g.V("A").until(__.not(outE("alpha"))).
repeat(out("alpha")).path().by(union(identity(), out("beta")).fold())
这将 return:
[[A, A1], [B], [C, A2]]
海事组织这就足够了。但是,如果您需要一组一致的 2 个条目,您可以这样做:
g.V("A").until(__.not(outE("alpha"))).repeat(out("alpha")).
path().by(union(identity(), coalesce(out("beta"), constant("N/A"))).fold())
...然后 return:
[[A, A1], [B, N/A], [C, A2]]
完成会话:
这是我的 gremlin-scala 解决方案,基于 Daniel 的回答。
val unionTraversal = __[(String, Vertex)].union(
__[Vertex].identity.map("blob" -> _),
__.out(Beta).map("beta" -> _)
).traversal
def pathTuplesToScalaTuples(path: Path) =
path.objects.asScala.map(_.asInstanceOf[java.util.ArrayList[(String, Vertex)]].asScala.toList).toList
val pathO = graph.V("A")
.until(_.not(_.out(Alpha)))
.repeat(_.out(Alpha))
.path.by(unionTraversal.fold).headOption
val tuples = pathO.map(pathTuplesToScalaTuples)
不幸的是,这涉及到一些实际使发出的顶点有用的问题。
首先,当将匿名遍历传递到联合时,步骤标签会被删除,因此您不能使用 .as("blob")
标记发出的集合——这就是将它们包装在带有字符串标签的元组中的解决方法对于.
其次,gremlin-scala 还没有 Path
的包装器(并且可能永远不会得到它,因为路径可以有任意结构)所以我们必须做一个丑陋的转换。