Titan:用于基于时间的有效图形查询的Gremlin或Java

时间:2014-10-11 16:11:40

标签: gremlin titan

我有以下基于时间的IP-> FQDN映射的简单图表。

enter image description here

我创建了这个图表如下

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();

我现在正在编写查询的过程,该查询找到了ip在给定时间绑定的fqdn。一些例子如下

  • fqdnFor(ip =" ip1",timestamp = 1)== fqdn1
  • fqdnFor(ip =" ip1",timestamp = 2)== fqdn1
  • fqdnFor(ip =" ip1",timestamp = 3)== fqdn2
  • fqdnFor(ip =" ip1",timestamp = 4)== fqdn2

这是我为计算这个而编写的gremlin查询,我相信这是正确的例子(ip =' ip1',t = 4)。

g.V.has('name', ip)
    .outE.has('timestamp', LESS_THAN_EQUAL, t)
    .order()
    .last()
    .inV()

我的问题现在如下。

  1. 如何修改此gremlin查询以返回不仅仅是顶点 但也是导致它的边缘。

  2. 根据我创建的索引,此查询是否最佳?如果我正确地理解了bindByTime索引,那么即使上面描述的图形包含例如从每个ip(ip1,... IP2)。

  3. 如何从java而不是gremlin控制台执行此查询?我希望找到类似于JDBC PreparedStatement的东西。

  4. 类似以下的sudo代码。

    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();
    

1 个答案:

答案 0 :(得分:1)

Q1的答案似乎是使用as和select的组合。

g.V.has('name', 'ip1').outE.has('timestamp', LESS_THAN_EQUAL, 3).order().last().as('e').inV().as('v').select(['e', 'v'])

如果我使用orderBy()请参阅下面的quote from the Titan 0.5 docs,那么Q2的答案似乎是肯定的。

  

混合索引支持本地和高效的排序。然而   orderBy方法中使用的属性键必须是以前的   添加到混合索引的本机结果排序支持。这是   在orderBy键与查询不同的情况下很重要   键。如果属性键不是索引的一部分,那么排序   需要将所有结果加载到内存中。

但是我似乎无法使用orderBy()

g.V.has('name', 'ip1').outE.has('timestamp', LESS_THAN_EQUAL, 3).orderBy('timestamp', Order.DESC).last().as('e').inV().as('v').select(['e', 'v'])

我收到以下异常

  

没有方法签名:   com.tinkerpop.gremlin.groovy.GremlinGroovyPipeline.orderBy()是   适用于参数类型:(java.lang.String,   com.thinkaurelius.titan.core.Order)值:[timestamp,DESC]可能   解决方案:order(),order(com.tinkerpop.gremlin.Tokens $ T),   顺序(com.tinkerpop.pipes.PipeFunction),   为了(com.tinkerpop.pipes.transform.TransformPipe $订单),   order(groovy.lang.Closure),every()

Q3的答案似乎并非如此。以下页面上的任何内容似乎都与PreparedStatement类似,后者非常易读并且可以防止查询注入。

https://github.com/tinkerpop/gremlin/wiki/Using-Gremlin-through-Java