2

I have a Gremlin query in the String format (for example "g.V()"). I want to execute this String without submitting it to the GremlinServer.

I use the below dependency:

<dependency>
    <groupId>org.apache.tinkerpop</groupId>
    <artifactId>gremlin-driver</artifactId>
    <version>3.3.1</version>
</dependency>

Is there any way?

stephen mallette
  • 45,298
  • 5
  • 67
  • 135

2 Answers2

6

You can execute Gremlin string directly in GremlinGroovyScriptEngine or through the GremlinExecutor (which just passes the string to the GremlinGroovyScriptEngine but has some additional features to it). Simple pass the Gremlin string to the appropriate eval() method and get back a result from that script evaluation. That's basically what Gremlin Server does internally.

You will likely need the gremlin-groovy dependency rather than gremlin-driver.

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • 1
    I don't know how to build or create GremlinExecutor, could you give me a java example for doing this and executing the query "g.V()"? – Fariba Hashemi May 12 '18 at 09:50
  • 1
    Both classes use a simple Builder pattern. Calling the `build()` method on either class will give you a `Builder` object where you can set additional construction configurations and then when done, just call `create()` on the builder. At the most simple level, just call `build().create()` on either class (maybe just use `GremlinGroovyScriptEngine` first until you determine your exact needs). – stephen mallette May 12 '18 at 10:30
  • I used this code and it works correctly: ScriptEngine engine = new GremlinGroovyScriptEngine(); Bindings bindings = engine.createBindings(); bindings.put("g", graph.traversal()); engine.eval("g.V()", bindings); Is it ok? – Fariba Hashemi May 14 '18 at 07:47
  • Can you say how to set graph config in your solution? – Fariba Hashemi May 14 '18 at 07:51
  • @stephenmallette I use GremlinExecutor to do this. (basically convert the gremlin query string to a java class). What **i think** I am seeing is that creating the compilationUnit (GroovyClassLoader::doParseClass) takes a long time the first time. This is through the parseClass method in the GremlinGroovyScriptEngine. From the second time onwards we see a real improvement as we cache the class. Just wondering if I could get some pointers on how I could address this – Ram K Aug 09 '18 at 23:41
  • There isn't much you can do except parameterize your traversals so that they hit the cache on future operations. You can't avoid compilation if you use the `GremlinGroovyScriptEngine`. http://tinkerpop.apache.org/docs/current/reference/#parameterized-scripts – stephen mallette Aug 10 '18 at 00:30
2

Adding a 'complete' example based on stephen answer+comment:

public static void main(String[] args) throws ScriptException, ExecutionException, InterruptedException {
    Graph graph = TinkerGraph.open();
    Configuration c = graph.configuration();
    GraphTraversalSource g = graph.traversal();

    // Creating graph
    Vertex marko = g.addV("person").property("name","marko").property("age",29).next();
    Vertex lop = g.addV("software").property("name","lop").property("lang","java").next();
    g.addE("created").from(marko).to(lop).property("weight",0.6d).iterate();
    g.io("test.xml").write().iterate(); // saving to file

    //standard query
    GraphTraversal<Vertex, Map<Object, Object>> javaQueryResult = g.V().hasLabel("person").valueMap();

    // preparing GremlinExecutor
    ConcurrentBindings b = new ConcurrentBindings();
    b.putIfAbsent("g", g);

    GremlinExecutor ge = GremlinExecutor.build().evaluationTimeout(15000L).globalBindings(b).create();

    CompletableFuture<Object> evalResult = ge.eval("g.V().hasLabel('person').valueMap()");
    GraphTraversal actualResult = (GraphTraversal) evalResult.get();
}

Simple debugging app to check how results evaluated from string compare to standard queries.

Using maven dependencies tinkergraph-gremlin gremlin-core gremlin-groovy, version 3.4.6

GriffoGoes
  • 715
  • 7
  • 17