I have the following simple graph of time based IP->FQDN mappings.
I created this graph as follows
TitanManagement mgmt = graph.getManagementSystem();
VertexLabel ip = mgmt.makeVertexLabel("ip").make();
VertexLabel fqdn = mgmt.makeVertexLabel("fqdn").make();
EdgeLabel bind = mgmt.makeEdgeLabel("bind").make();
final PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).make();
TitanGraphIndex namei = mgmt.buildIndex("name", Vertex.class).addKey(name).unique().buildCompositeIndex();
mgmt.setConsistency(namei, ConsistencyModifier.LOCK);
final PropertyKey timestamp = mgmt.makePropertyKey("timestamp").dataType(Integer.class).make();
mgmt.buildEdgeIndex(bind, "bindByTime", Direction.BOTH, Order.DESC, timestamp);
mgmt.commit();
TitanTransaction tx = graph.newTransaction();
Vertex ip1 = tx.addVertexWithLabel("ip");
ip1.setProperty("name", "ip1");
Vertex ip2 = tx.addVertexWithLabel("ip");
ip2.setProperty("name", "ip2");
Vertex fqdn1 = tx.addVertexWithLabel("fqdn");
fqdn1.setProperty("name", "fqdn1");
Vertex fqdn2 = tx.addVertexWithLabel("fqdn");
fqdn2.setProperty("name", "fqdn2");
ip1.addEdge("bind", fqdn1).setProperty("timestamp", 1);
ip2.addEdge("bind", fqdn2).setProperty("timestamp", 2);
ip1.addEdge("bind", fqdn2).setProperty("timestamp", 3);
tx.commit();
I am now in the process of writing a query which finds the fqdn that an ip was bound to at a given time. Some examples follow
- fqdnFor(ip="ip1", timestamp=1) == fqdn1
- fqdnFor(ip="ip1", timestamp=2) == fqdn1
- fqdnFor(ip="ip1", timestamp=3) == fqdn2
- fqdnFor(ip="ip1", timestamp=4) == fqdn2
Here is the gremlin query I have written to compute this, I believe this is correct given for example (ip='ip1', t=4).
g.V.has('name', ip)
.outE.has('timestamp', LESS_THAN_EQUAL, t)
.order()
.last()
.inV()
My questions are now as follows.
How would I modify this gremlin query to return not just the vertex but also the edge that lead to it.
Is this query optimal given the indexes I have created? If I understand the bindByTime index correctly this query should be as efficient (take the same computation time) even if the graph depicted above contained for example a million bind edges (t1, t2, ... t1000000) outgoing from each ip (ip1, ip2).
How would I execute this query from java instead of from the gremlin console? I was hoping to find something akin to JDBC PreparedStatement.
Something like the following sudo code.
PreparedGremlinQuery query = new PreparedGremlinQuery("V.has('name', :ip).outE.has('timestamp', LESS_THAN_EQUAL, :t).order().last().inV()");
query.put(1, "ip1");
query.put(2, 3);
Result r = query.execute();