I have a vertex that is set with properties startDate
and endDate
:
Date start = new Date();
Date end = Date.from(start.toInstant().plusSeconds(600));
g.V(8L).property("startDate", start).property("endDate", end).next();
Now I want to compute the difference endDate-startDate
and I could do that with sack()
:
g.V(8L)
.sack(Operator.assign).by(values("endDate").map(it -> ((Date)it.get()).getTime()))
.sack(Operator.minus).by(values("startDate").map(it -> ((Date)it.get()).getTime()))
.sack()
However, this does not work if the traversal is sent remotely.
By converting the Lambda into Lambda.function(), the below traversal works remotely:
String funcGetTime = "v -> ((Date)v.get()).getTime()";
g.V(8L)
.sack(Operator.assign).by(values("endDate").map(Lambda.function(funcGetTime)))
.sack(Operator.minus).by(values("startDate").map(Lambda.function(funcGetTime)))
.sack()
However, the traversal no longer works in my in-memory graph local setup. The error message is:
java.lang.IllegalArgumentException: The provided traverser does not map to a value: v[8]->[PropertiesStep([endDate],value), LambdaMapStep(lambda[v -> ((Date)v.get()).getTime()])]
My question is: Is there a traversal that does the same thing (calculate the diff between endDate and startDate) that can work for both local and remote? I need it since my unit tests are run locally with in-memory graph while during running, my application invokes the traversal by connecting to a remote graph.
The reason I have to compute the diff in the traversal (instead of doing in my application) is because I want to use this diff further in the traversal later.
Thanks.
Gremlin does not yet have datetime operators that can help you with this and as you've found a remote lambda won't evaluate in the same fashion as a local one. The remote one requires that the entire traversal be evaluated in the GremlinGroovyScriptEngine
, which basically takes the Gremlin Bytecode
, runs it through the GroovyTranslator
and then evaluates the whole thing as a script. I can simulate that in the Gremlin Console as follows:
gremlin> evaluate(GroovyTranslator.of("g").translate(g.V().map(Lambda.function("v -> v"))).script)
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
If you need the remote to work the same as local, I can't think of any workarounds short of either the above approach or by storing your date as long (perhaps as a form of denormalization) so that you can do the calculations directly without having to the DateTime
conversion. Hopefully, Gremlin will get better date operations in future versions.