Closed joebernard closed 8 years ago
Sorry for the late answer, I was on vacation and didn't see your message. I'll have a look into your issue shortly.
You should be able to do something along the lines of :
const client = Gremlin.createClient();
client.execute('graph.addVertex("date", new Date(someDate))', { someDate: new Date() }, (err, results) => {
console.log(results[0]) // notice how results is always an array
});
I haven't set any server constraints but it still seems to work here (note: you'll want to check the json output. As you'll see you should get a timestamp back)
JavaScript Date
objects are stringified as ISO8601 strings, so this is what will be sent to Gremlin Server when you specify a Date
object as a bound parameter. You then have to manually cast that parameter/ISO8601 string back as a Date
object within the context of your Gremlin query.
Dylan's example is correct.
Thank you for the responses. I ran the example provided by @PommeVerte but the client throws an error:
{ "errorMessage": "null (Error 597)", "errorType": "Error", "stackTrace": [ "GremlinClient.handleProtocolMessage (/var/task/node_modules/gremlin/lib/GremlinClient.js:158:39)", "WebSocketGremlinConnection.
(/var/task/node_modules/gremlin/lib/GremlinClient.js:109:23)", "WebSocketGremlinConnection.emit (events.js:95:17)", "WebSocketGremlinConnection.handleMessage (/var/task/node_modules/gremlin/lib/WebSocketGremlinConnection.js:67:12)", "WebSocketGremlinConnection._this.ws.onmessage (/var/task/node_modules/gremlin/lib/WebSocketGremlinConnection.js:45:20)", "WebSocket.onMessage (/var/task/node_modules/ws/lib/WebSocket.js:418:14)", "WebSocket.emit (events.js:98:17)", "Receiver.ontext (/var/task/node_modules/ws/lib/WebSocket.js:816:10)", "/var/task/node_modules/ws/lib/Receiver.js:477:18", "Receiver.applyExtensions (/var/task/node_modules/ws/lib/Receiver.js:364:5)" ] }
The error seems related to connectivity which is strange. My code:
gremlin.client.execute('graph.addVertex("createdDate", new Date(someDate))', { someDate: new Date() }, function(err, results) {
console.log(results[0]);
});
It only throws this error if I pass the date as a parameter. For example, this works:
client.execute('graph.addVertex("createdDate", new Date())', function(err, results) {
console.log(results[0]);
});
Hey, I didn't test my code, just meant for it to serve as a hint. I had a quick look at this and it's pretty interesting.
either of the following should work :
gremlin.client.execute('graph.addVertex("createdDate", new Date(someDate))', { someDate: new Date().toString() }, function(err, results) {
console.log(results);
});
or
gremlin.client.execute('graph.addVertex("createdDate", someDate)', { someDate: new Date() }, function(err, results) {
console.log(results);
});
It looks like the binding passes the object on somehow. I'm quite impressed.
Your first example works great. The second is cleaner but unfortunately throws an error:
{ "errorMessage": "Value [2016-03-18T16:40:09.694Z] is not an instance of the expected data type for property key [createdDate] and cannot be converted. Expected: class java.util.Date, found: class java.lang.String (Error 597)", "errorType": "Error", "stackTrace": [ "GremlinClient.handleProtocolMessage (/var/task/node_modules/gremlin/lib/GremlinClient.js:158:39)", "WebSocketGremlinConnection.
(/var/task/node_modules/gremlin/lib/GremlinClient.js:109:23)", "WebSocketGremlinConnection.emit (events.js:95:17)", "WebSocketGremlinConnection.handleMessage (/var/task/node_modules/gremlin/lib/WebSocketGremlinConnection.js:67:12)", "WebSocketGremlinConnection._this.ws.onmessage (/var/task/node_modules/gremlin/lib/WebSocketGremlinConnection.js:45:20)", "WebSocket.onMessage (/var/task/node_modules/ws/lib/WebSocket.js:418:14)", "WebSocket.emit (events.js:98:17)", "Receiver.ontext (/var/task/node_modules/ws/lib/WebSocket.js:816:10)", "/var/task/node_modules/ws/lib/Receiver.js:477:18", "Receiver.applyExtensions (/var/task/node_modules/ws/lib/Receiver.js:364:5)" ] }
I have createdDate
explicitly defined as a Date
. Somehow it is casting the param someDate
as a java.lang.String
instead of an java.util.Date
. Not sure if there's a way to force that cast or not.
Hmmm, well I'm glad one of those is working for you. It's weird because the following snippet (original suggestion) :
const client = Gremlin.createClient();
client.execute('graph.addVertex("date", new Date(someDate))', { someDate: new Date() }, (err, results) => {
console.log(results[0]) // notice how results is always an array
});
Throws the following error. Basically complaining about doing new Date(Date)
. I'm using gremlin-server
v3.1.2-SNAPSHOT
. There was a PR (https://github.com/apache/incubator-tinkerpop/commit/cee96fdb29fe354837845da961c0f6252e007b5a) around mid-feb regarding serializing/deserializing of times and dates in GraphSON
. It's possible that I'm riding that wave and that that's why I'm getting this result.
[WARN] AbstractEvalOpProcessor - Exception processing a script on request [RequestMessage{, requestId=708657d0-ed2a-11e5-82f4-3d8337a7ac8d, op='eval', processor='', args={gremlin=graph.addVertex("date", new Date(someDate)), bindings={someDate=2016-03-18T16:57:03.692Z}, accept=application/json, language=gremlin-groovy}}].
java.lang.IllegalArgumentException
at java.util.Date.parse(Date.java:617)
at java.util.Date.<init>(Date.java:274)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:247)
at Script2.run(Script2.groovy:1)
at org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.eval(GremlinGroovyScriptEngine.java:548)
at org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.eval(GremlinGroovyScriptEngine.java:387)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
at org.apache.tinkerpop.gremlin.groovy.engine.ScriptEngines.eval(ScriptEngines.java:102)
at org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.lambda$eval$24(GremlinExecutor.java:258)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Yeah that was my original problem, parameterizing dates. @jbmusso Is this an issue or should we just use the method @PommeVerte outlined in his second example?
For reference I'm on Gremlin 3.0.1-incubating
.
I'm pretty sure this behavior is normal. Maybe after 3.1.2
is released you'll be able to use the other example I gave (that failed for you). In the meantime there isn't really any way for the driver to pass on an object so you will need to type cast it in your query.
As a side node to @jbmusso : Once the unpacking of binary data functions properly there's the possibility to implement application/vnd.gremlin-v1.0+json
that allows to explicitly type the elements you send. But I don't really know if this is something many people would use (this Date
case will probably be resolved by 3.1.2
and there aren't many other cases I can think of short of plugin+client developers).
What is the best way to pass a date to gremlin? When I try with
new Date()
ornew Date().toISOString()
I log the following error:Is it possible to cast to a java
Date
somehow?