【问题标题】:In Gremlin how does map() really work?在 Gremlin 中,map() 是如何工作的?
【发布时间】:2018-06-25 02:36:59
【问题描述】:

为什么这两个会产生不同的结果?

graph.traversal()
   .V().map(__.out("contains"))
.valueMap(true).next(100)

相比

graph.traversal()
   .V().out("contains")
.valueMap(true).next(100)

为什么我更喜欢 map 而不是直接调用 .out() 方法? 通过这种方式,我可以组织我的代码,我可以在其中获取方法的遍历,并将“映射”到现有的遍历。

【问题讨论】:

    标签: java gremlin tinkerpop3 tinkergraph


    【解决方案1】:

    在考虑这个问题时,请回想一下 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]]
    

    【讨论】:

    • 谢谢你,这太棒了。
    • 问题是我应该这样组织我的代码吗?在代码中传递遍历,还是使用 map 并接受来自其他地方的遍历?
    • 我不认为从函数构造匿名遍历然后在map() 中使用它们是错误的,但这可能会使您的Gremlin 难以阅读。根据您的具体操作,您还可能使查询分析器更难正确优化您的遍历。如果你有一些可重复使用的 Gremlin,那么你最好构建一个 DSL datastax.com/dev/blog/gremlin-dsls-in-java-with-dse-graph
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 2016-06-24
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多