我正在尝试执行数学查询。
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)]
NoOpBarrierStep(2500)
是什么意思?答案 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()。