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

Titan:Gremlin或Java用于高效的基于时间的图形查询,gremlin,titan,Gremlin,Titan,我有以下基于时间的IP->FQDN映射的简单图 我创建了这个图,如下所示 TitanManagement mgmt = graph.getManagementSystem(); VertexLabel ip = mgmt.makeVertexLabel("ip").make(); VertexLabel fqdn = mgmt.makeVertexLabel("fqdn").make(); EdgeLabel bind = mgmt.makeEdgeLabel("bind").make();

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

我创建了这个图,如下所示

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”,时间戳=1)=fqdn1
  • fqdnFor(ip=“ip1”,时间戳=2)=fqdn1
  • fqdnFor(ip=“ip1”,时间戳=3)=fqdn2
  • fqdnFor(ip=“ip1”,时间戳=4)=fqdn2
这是我编写的用于计算这个的gremlin查询,我相信这是正确的,例如(ip='ip1',t=4)

我现在的问题如下

  • 如何修改这个gremlin查询,使其不仅返回顶点 但也有导致它的边缘

  • 考虑到我创建的索引,这个查询是最优的吗?如果我正确理解bindByTime索引,那么即使上面描述的图包含例如从每个ip(ip1,ip2)传出的一百万条绑定边(t1,t2,…t1000000),该查询也应该同样有效(采用相同的计算时间)

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

  • 类似于下面的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();
    

    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()的话,第2个问题的答案似乎是肯定的,如下所示

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

    但是,我似乎不能使用orderBy()

    我得到以下例外

    无方法签名: gremlingroovypepeline.orderBy()是 适用于参数类型:(java.lang.String, com.thinkaurelius.titan.core.Order)值:[时间戳,描述]可能 解决方案:order(),order(com.tinkerpop.gremlin.Tokens$T), 订单(com.tinkerpop.pipes.PipeFunction), 订单(com.tinkerpop.pipes.transform.TransformPipe$order), order(groovy.lang.Closure),every()

    第三季度的答案似乎是否定的。下一页中的任何内容似乎都与PreparedStatement相似,PreparedStatement可读性强,可以防止查询注入

    g.V.has('name', 'ip1').outE.has('timestamp', LESS_THAN_EQUAL, 3).order().last().as('e').inV().as('v').select(['e', 'v'])
    
    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'])