Базы данных графов: получение самых сложных связей с помощью 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())
При визуальном отображении