Есть ли лучший способ для моделирования моих сущностей и отношений для графа БД (с использованием gremlin)? - PullRequest
1 голос
/ 05 ноября 2019

У меня есть данные, смоделированные на 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;
      }

    }

  }
}

Он работает и создает объекты в базе данных Нептуна, но, как вы видите, не оптимизирован по производительности. Есть ли лучший способ сделать это?

1 Ответ

2 голосов
/ 06 ноября 2019

Для объектов 10k я бы использовал пакетный загрузчик Neptune , который берет CSV-файл из s3 и загружает его в Neptune эффективно. В вашем случае поток будет - сериализовать сущности в csv, загрузить в s3 и вызвать 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 запросов.

...