提供的遍历未映射到值

时间:2020-06-24 10:36:16

标签: gremlin tinkerpop tinkerpop3

我正在尝试执行数学查询。

gts.V()
.hasLabel("account")
.has("id",42)
.both("account_label1").as("label1")
.and(__.identity()
        .project("a","b")
        .by(__.identity()
                .both("label1_label2")
                .both("label2_label3")
                .values("createTime"))
        .by(__.identity()
                .both("label1_label4")
                .both("label4_label5")
                .values("launchTime"))
        .math("floor((a-b)/(86400))").is(100))
.select("label1")
.toList()

以上查询失败,并显示错误

The provided traverser does not map to a value: v[137]->[IdentityStep, VertexStep(BOTH,[label1_label2],vertex), VertexStep(BOTH,[label2_label3],vertex), NoOpBarrierStep(2500), PropertiesStep([createTime],value)]
  1. 为何葛瑞姆林注射NoOpBarrierStep?
  2. NoOpBarrierStep(2500)是什么意思?
  3. 相同的正确的gremlin查询是什么?

1 个答案:

答案 0 :(得分:1)

使用project()时,它期望每个by()调制器都有一个值,并且该值不应产生空的Iterator。这是一个简单的示例:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().project('x').by(out())
==>[x:v[3]]
The provided traverser does not map to a value: v[2]->[VertexStep(OUT,vertex)]
Type ':help' or ':h' for help.
Display stack trace? [yN]

第一个顶点能够遍历out(),但是由project()处理的下一个顶点没有传出边,因此会产生此错误。在您的情况下,这仅意味着并非所有的遍历器都可以遍历both().both(),或者如果可以,您将要确保它们都具有“ createTime”属性值。这些情况中的任何一种都可能导致问题。

您可以通过多种方式解决此问题。显然,如果这是一个数据问题,您可以简单地修复数据并始终假定遍历路径正确。如果不是这种情况,那么如果遍历路径不可用,则需要编写Gremlin以便更加宽容。就我而言,我可以做到:

gremlin> g.V().project('x').by(out().fold())
==>[x:[v[3],v[2],v[4]]]
==>[x:[]]
==>[x:[]]
==>[x:[v[5],v[3]]]
==>[x:[]]
==>[x:[v[3]]]

也许您可能会这样做:

by(coalesce(both("label1_label2").both("label2_label3").values("createTime"),
            constant('n/a')))

请注意,您无需为匿名遍历的开始指定identity()

最后,在回答有关NoOpBarrierStep的问题时,这一步被注入到遍历中,Gremlin认为遍历可以利用bulking optimization。您也可以通过barrier()步骤自己添加它们。这是TinkerPop参考文档中对“散装”的简要说明:

“批量优化”背后的理论很简单。如果在顶点1有一百万个遍历器,则无需计算一百万个both()计算。取而代之的是,将这100万个遍历器表示为一个Traverser.bulk()等于一百万的遍历器,并执行一次both()。