将BatchGraph与TitanGraph

时间:2016-01-28 22:23:30

标签: database cassandra batch-processing graph-databases titan

我正在尝试使用BatchGraph在Titan中加载数据。使用TitanGraph作为对象参数。

根据Tinkerpop的Batch Implementation,这就是实施的方式:

TitanGraph g = TitanFactory.open("titan-cassandra.properties");
BatchGraph bgraph = new BatchGraph( g, VertexIDType.STRING, 1000);

但是在BatchGraph构造函数中需要TrasanctionalGraph对象。所以,当我把它投射为:

TitanGraph g = TitanFactory.open("titan-cassandra.properties");

 BatchGraph bgraph = new BatchGraph( (TransactionalGraph) g, VertexIDType.STRING, 1000)

这会出现以下错误:

Exception in thread "main" java.lang.ClassCastException:
com.thinkaurelius.titan.graphdb.database.StandardTitanGraph cannot be cast to com.tinkerpop.blueprints.TransactionalGraph

在这种情况下如何使用BatchGraph?如何处理?

我正在使用Titan 1.0.0和Blueprints 2.7.0以及cassandra 2.2.4版。

感谢。

2 个答案:

答案 0 :(得分:7)

你无法使用蓝图(TinkerPop 2.x)中的BatchGraph和Titan 1.0。它们不兼容。 Titan 1.0支持TinkerPop 3.x,TinkerPop 3.x中没有BatchGraph

BatchGraph很容易重新创建。它基本上只是隐藏了新插入的顶点的缓存,这些顶点跟踪它们的id以供将来查找。使用此内存缓存将比Titan的索引查找更快。您可以使用guava之类的现有缓存来复制它。

如果您的图表非常大,则可以使用BLVP(BulkLoaderVertexProgram)加载数据。有一些证明here。请注意,上面BLVP的链接是Titan 1.0.0当前支持的版本 - 文档和支持已针对未来的1.1.0 here进行了改进。还有更好的BLVP usage with Spark和其他提供商的例子。

答案 1 :(得分:0)

重新创建BatchGraph行为的快速而天真的实现可能如下(使用Google的Guava库作为缓存):

import com.google.common.cache.*;

// Define schema & indexes...
...

// Cache definition 
// In my case, I can handle all vertices in memory
cacheSize = 2000000;
vertexCache = CacheBuilder.newBuilder()
  .maximumSize(cacheSize)
  .expireAfterWrite(10, TimeUnit.MINUTES)
  .build();

nUsers = 0
println 'Loading vertices...';
// Load vertices
new File('/tmp/vertices.txt').eachLine {
  try {
    fields = it.split('\t').take(8);
    userId = fields[0];
    isPublic = fields[1] == '1' ? true : false;
    completionPercentage = fields[2]
    gender = fields[3] == '1' ? 'male' : 'female';
    region = fields[4];
    lastLogin = fields[5];
    registration = fields[6];
    age = fields[7] as int;
    v = graph.addVertex('userId', userId, 'isPublic', isPublic, 'completionPercentage', completionPercentage, 'gender', gender, 'region', region, 'lastLogin', lastLogin, 'registration', registration, 'age', age);
    // Add vertex to the cache
    vertexCache.put(userId, v);
  } catch (Exception e) {
    // Silently skip...
    // e.printStackTrace();
  }
  nUsers += 1
  if (nUsers % 10000 == 0) {
    println String.valueOf(nUsers) + ' vertices loaded so far...';
    graph.tx().commit();
  }
};
println 'Vertices load finished';

// Load relations
nLinks = 0;
println 'Loading links ...';
new File('/tmp/edges.txt').eachLine {
  try {
    fields = it.split('\t');
    from = fields[0];
    to = fields[1];
    fromVertex = vertexCache.getIfPresent(from);
    toVertex = vertexCache.getIfPresent(to);
    if (fromVertex != null && toVertex != null)
      toVertex.addEdge('connectedTo', fromVertex);
  } catch (Exception e) {
    // Silently skip...
    e.printStackTrace();
  }
  nLinks += 1;
  if (nLinks % 10000 == 0) {
    println String.valueOf(nLinks) + ' links loaded so far...';
    graph.tx().commit();
  }
};

graph.close()

我使用带有~1.7M顶点和~30M边缘的图形进行了测试(在存储后端激活了批量加载,这迫使您事先定义所有模式,但实际上这被认为是一种很好的做法)并且它是在不到10分钟的时间内成功加载。在创建边时使用存储索引进行顶点检索时,加载过程需要1个多小时。