我正在尝试使用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版。
感谢。
答案 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个多小时。