Базы данных графов: получение самых сложных связей с помощью Gremlin

Я пытаюсь написать запрос Gremlin, чтобы найти список пройденных вершин и ребер (с их свойствами), возвращая самую сложную (т.е. наибольшее количество) вершин на основе начальной вершины.

Другими словами, я хочу получить пациентов с наибольшим количеством кодов, но между пациентами и кодами нет прямой связи. Это взаимосвязь и направление:Patient->Diagnosis<-Code

Вот моя попытка:

      g.V().hasLabel('Patient'). 
  outE().inV().
  inE().outV().
  path().
    by(elementMap()).
  order().
    by(count(local), asc).
  tail(2).
  unfold().
  toList()

Я хотел, чтобы это возвращало вершины пациентов с их пройденными ребрами/вершинами, только первые 2 на основе количества кодов, возвращаемых на одного пациента. Вот что я получил:

вершина одного пациента с пересекающимися ребрами/узлами

Вот пример вставки для воспроизведения тех же отношений:

      g
.addV('pat').property(id, 'p-0')
.addV('pat').property(id, 'p-1')
.addV('pat').property(id, 'p-2')
.addV('diag').property(id, 'd-0')
.addV('diag').property(id, 'd-1')
.addV('diag').property(id, 'd-2')
.addV('code').property(id, 'c-0')
.addV('code').property(id, 'c-1')
.V('p-0').addE('contracted').to(V('d-0'))
.V('p-0').addE('contracted').to(V('d-1'))
.V('p-0').addE('contracted').to(V('d-2'))
.V('p-1').addE('contracted').to(V('d-1'))
.V('p-2').addE('contracted').to(V('d-2'))
.V('c-0').addE('includes').to(V('d-0'))
.V('c-1').addE('includes').to(V('d-0'))
.V('c-1').addE('includes').to(V('d-1'))
.V('c-2').addE('includes').to(V('d-1'))

Это пример формата, который я хотел бы вернуть:я использовал «.path().by(elementMap()).unfold().toList()» после шагов вершин и ребер, чтобы получить это.

Я хочу, чтобы на выходе были вершины и ребра, которые создадут такой граф:

Как видите, из трех пациентов я хочу вернуть топ-2 самых сложных пациентов (по количеству кодов, которые имеют их диагнозы). Я не хочу возвращать пациента по одному коду.

1 ответ

Спасибо за предоставленный пример графика. Это действительно помогает. Использование этого запроса помогает просто увидеть график визуально.

      g.V().hasLabel('pat').
  outE().inV().
  inE().outV().
  simplePath().
  path().by(elementMap())

Который с помощью граф-блокнота выдаёт:

Чтобы найти количество кодов для каждого начального пациента, мы могли бы сделать это. Он основан на предыдущем запросе, но фильтруется с использованием меток границ.

      g.V().hasLabel('pat').as('p').
  out('contracted').
  group().
    by(select('p').id()).
    by(in('includes').count())

который даст нам коды, связанные с каждым пациентом

      {'p-0': 3, 'p-2': 0, 'p-1': 1}

Однако вам может не понадобиться двойной учет, когда код является общим для более чем одного диагноза. В таком случае мы можемdedupрезультаты.

      g.V().hasLabel('pat').as('p').
  out('contracted').
  group().
    by(select('p').id()).
    by(in('includes').dedup().count())

который уменьшает счет для p-0 до 2 и полностью удаляет p-2, поскольку кодов нет.

      {'p-0': 2, 'p-1': 1}

ОБНОВЛЕНО

Основываясь на дополнительном обсуждении в комментариях, этот запрос может использоватьgroupCountрезультаты в качестве фильтра.

      g.V().hasLabel('pat').as('p').
  outE('contracted').inV().
  where(
    group().
      by(select('p').id()).
      by(in('includes').dedup().count()).
    select(values).unfold().is(2)).
    inE().outV().
    path().by(elementMap())

При визуальном отображении

Другие вопросы по тегам