我有一个在Java上建模为实体和关系的数据。每个实体都有一个关系列表。并且我们即将到来的请求可以有一个通过实体请求进入的实体列表,需要在GraphDB中创建(使用Neptune)并使用gremlin访问它。我必须遍历实体列表一次以在图形中创建顶点,然后再次遍历实体,同时遍历每个关系以根据关系创建边。这不是处理此问题的最优雅的方法,所以有没有一种方法可以优化我的数据模型和/或gremlin查询?请参阅下面的代码以供参考。
public class EntityRequest{
Set<Entity> entities;
// getter
// builder
// constructors etc
}
public class Entity{
String id;
String entityType;
List<String, Object> attributes;
List<Relationship> relationships;
// getter
// builder
// constructors etc
}
public class Relationship{
String id;
String type;
Map<String, Object> RelationshipMetaData;
}
public EntityCreationServiceImpl{
public void createEntitiesinGraph(EntityRequest request, GraphTraversalSource g){
// any kind of loop
Set<Entity> eSet = request.getEntities();
loop-through-entities(e) -> {
create all vertices using e;
};
// any kind of loop
loop-through-entities(e) -> {
loop-through-list-of-relationships-for-each-entity(r) ->{
create all edges for e;
}
}
}
}
它正在neptune数据库中工作并创建实体,但是如您所见,它未对性能进行优化。有更好的方法吗?
对于10k实体,我将使用Neptune bulk loader,它从s3中获取csv文件,并将其有效地上传到Neptune。在您的情况下,流程是-将实体序列化为csv,上传到s3,然后调用load api。
但是,对于多次输入的通常情况,这可能是一个过大的杀伤力。
由于数据库可能已经有一些顶点,所以应该使用合并搜索顶点是否存在,否则创建顶点。您可以在同一查询中链接边缘创建,如果不存在,可以选择创建边缘目标顶点:
g.V().has(foo,bar).fold().coalesce(unfold(),addV(type).property(foo,bar)).as('v')
.addE().from('v).to(V().has(...).fold().coalesce(unfold(),addV(...))
.addE().from('v).to(V().has(...).fold().coalesce(unfold(),addV(...))
这样,您将只迭代一次条目,并执行n个查询。