Gremlin — Просмотр графика на разных уровнях (иерархиях)

Отказ от ответственности: я больше склоняюсь к миру реляционных баз данных, поэтому у меня могут быть некоторые неправильные представления о том, как лучше всего хранить графовые базы данных и работать с ними.

В любом случае, допустим, у меня есть данные с некоторой иерархией. Допустим, у меня есть следующая иерархия:

  • Еда / Фрукты / Апельсин
  • Еда / Овощи / Салат
  • Еда / Овощи / Лук
  • блюда / Тайская / Пхад Тай
  • блюда / Тайская / Ларб Гай
  • Блюда / Десерт / Апельсиновый торт
  • Блюда / Блюдо / Салат Цезарь

И вдобавок,

На моем графике у меня есть вершины для каждого элемента последнего уровня в иерархии, и у каждого из них есть 2 свойства, чтобы узнать, что такое полная иерархия. Например: Помидор обладает свойствами level1: 'Food', level2: 'Fruit'.

Кроме того, у меня есть ребра used_inкогда какой-то ингредиент используется в блюде.

Все ребра находятся между вершинами (элементы последнего уровня в иерархии). Теперь я хотел бы иметь возможность посмотреть на график более высокого уровня, основанный на level2. Например, я хотел бы иметь возможность видеть: Fruit -> used_in -> Desert Vegetable -> used_in -> Thai

График выглядит следующим образом:

И я хочу запросить график, чтобы получить следующий результат:

Итак, есть ли способ сгруппировать вершины по некоторой комбинации полей (в данном случае ключом является комбинация полей уровня 1 и уровня 2), чтобы остались ребра, связанные между этими группами? Если есть какой-то другой способ, которым я должен моделировать свои данные? Например, добавлять метки на основе всех элементов иерархии?

Чтобы создать график:

      g.addV('Orange').property(id, 'Orange').property('level3', 'Orange').property('level2', 'Fruit').property('level1', 'Food')
.addV('Lettuce').property(id, 'Lettuce').property('level3', 'Lettuce').property('level2', 'Vegetable').property('level1', 'Food')
.addV('Onion').property(id, 'Onion').property('level3', 'Onion').property('level2', 'Vegetable').property('level1', 'Food')
.addV('Phad Thai').property(id, 'Phad Thai').property('level3', 'Spoon').property('level2', 'Thai').property('level1', 'Dishes')
.addV('Larb Gai').property(id, 'Larb Gai').property('level3', 'Fork').property('level2', 'Thai').property('level1', 'Dishes')
.addV('Orange Cake').property(id, 'Orange Cake').property('level3', 'Orange Crepe').property('level2', 'Desert').property('level1', 'Dishes')
.addV('Ceasars Salad').property(id, 'Ceasars Salad').property('level3', 'Ceasars Salad').property('level2', 'Salads').property('level1', 'Dishes')
.addE('used_in').from(g.V().has(id, 'Orange')).to(g.V().has(id, 'Orange Cake'))
.addE('used_in').from(g.V().has(id, 'Lettuce')).to(g.V().has(id, 'Ceasars Salad'))
.addE('used_in').from(g.V().has(id, 'Onion')).to(g.V().has(id, 'Phad Thai'))
.addE('used_in').from(g.V().has(id, 'Onion')).to(g.V().has(id, 'Larb Gai'))
.addE('used_in').from(g.V().has(id, 'Lettuce')).to(g.V().has(id, 'Larb Gai'))
.iterate()

Заранее спасибо! :)

1 ответ

Я переформатировал этапы создания графика и удалил g.V()и заменили просто V()для всех средних шагов обхода. Это больше не будет работать в TinkerPop 3.5.x и более поздних версиях, поскольку эта форма устарела. У него есть плохие побочные эффекты, о которых большинство пользователей не подозревают. Я думаю, что изменение модели данных может быть хорошей идеей.

Глядя на данные, вы действительно используете свойства таким образом, который имитирует то, в чем хороши ребра. Например, почему бы не иметь ребра с такими метками, как level1и использовать эти ребра для соединения соответствующих вершин? Во всяком случае, вот создание переформатированного графика.

      g.addV('Orange').
    property(id, 'Orange').
    property('level3', 'Orange').
    property('level2', 'Fruit').
    property('level1', 'Food').
  addV('Lettuce').
    property(id, 'Lettuce').
    property('level3', 'Lettuce').
    property('level2', 'Vegetable').
    property('level1', 'Food').
  addV('Onion').
    property(id, 'Onion').
    property('level3', 'Onion').
    property('level2', 'Vegetable').
    property('level1', 'Food').
  addV('Phad Thai').
    property(id, 'Phad Thai').
    property('level3', 'Spoon').
    property('level2', 'Thai').
    property('level1', 'Dishes').
  addV('Larb Gai').
    property(id, 'Larb Gai').
    property('level3', 'Fork').
    property('level2', 'Thai').
    property('level1', 'Dishes').
  addV('Orange Cake').
    property(id, 'Orange Cake').
    property('level3', 'Orange Crepe').
    property('level2', 'Desert').
    property('level1', 'Dishes').
  addV('Ceasars Salad').
    property(id, 'Ceasars Salad').
    property('level3', 'Ceasars Salad').
    property('level2', 'Salads').
    property('level1', 'Dishes').
  addE('used_in').
    from(V().has(id, 'Orange')).
    to(V().has(id, 'Orange Cake')).
  addE('used_in').
    from(V().has(id, 'Lettuce')).
    to(V().has(id, 'Ceasars Salad')).
  addE('used_in').
    from(V().has(id, 'Onion')).
    to(V().has(id, 'Phad Thai')).
  addE('used_in').
    from(V().has(id, 'Onion')).
    to(V().has(id, 'Larb Gai')).
  addE('used_in').
    from(V().has(id, 'Lettuce')).
    to(V().has(id, 'Larb Gai'))              

Для начала, и если вам нужно больше, я могу отредактировать вопрос, мы можем использовать pathшаг, чтобы создать отношения, показанные на ваших диаграммах. Однако я бы рассмотрел возможность изменения модели данных.

      g.V().has('level2','Fruit').
  outE('used_in').
  inV().
  path().
    by('level2').
    by(label).
    by('level2')

Что находит:

      [Fruit, used_in, Desert]
Другие вопросы по тегам