Неровный массив результатов Gremlin Query

Пожалуйста, не могли бы вы помочь мне написать запрос, который возвращает каждую исходную вершину в моем обходе вместе с соответствующими ребрами и вершинами в виде массивов для каждой такой исходной вершины? Короче говоря, мне нужен набор результатов, содержащий массив из трех кортежей, где элемент 1 каждого кортежа является исходной вершиной, а элементы 2 и 3 являются связанными массивами.

Спасибо!

РЕДАКТИРОВАТЬ 1: расширены данные графика и добавлены мои текущие проблемные запросы. РЕДАКТИРОВАТЬ 2: Улучшен пример кода графа Gremlin (извиняюсь, не думал, что кто-то действительно запустит его.)

Образец графика

g.addV("blueprint").property("name","Mall").
addV("blueprint").property("name","HousingComplex").
addV("blueprint").property("name","Airfield").
addV("architect").property("name","Tom").
addV("architect").property("name","Jerry").
addV("architect").property("name","Sylvester").
addV("buildingCategory").property("name","Civil").
addV("buildingCategory").property("name","Commercial").
addV("buildingCategory").property("name","Industrial").
addV("buildingCategory").property("name","Military").
addV("buildingCategory").property("name","Resnameential").
V().has("name","Tom").addE("designed").to(V().has("name","HousingComplex")).
V().has("name","Tom").addE("assisted").to(V().has("name","Mall")).
V().has("name","Jerry").addE("designed").to(V().has("name","Airfield")).
V().has("name","Jerry").addE("assisted").to(V().has("name","HousingComplex")).
V().has("name","Sylvester").addE("designed").to(V().has("name","Mall")).
V().has("name","Sylvester").addE("assisted").to(V().has("name","Airfield")).
V().has("name","Sylvester").addE("assisted").to(V().has("name","HousingComplex")).
V().has("name","Mall").addE("classification").to(V().has("name","Commercial")).
V().has("name","HousingComplex").addE("classification").to(V().has("name","Resnameential")).
V().has("name","Airfield").addE("classification").to(V().has("name","Civil"))

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

Необходимые результаты запроса

Мне нужно вернуть каждую вершину чертежа в качестве основы с каждым из связанных с ней ребер / вершин в виде массивов.

Мое текущее решение

В настоящее время я выполняю этот очень громоздкий запрос, который получает чертежи и назначает метку, получает архитекторов и назначает метку, а затем выбирает обе метки. Решение в порядке; однако это становится беспорядочным, когда мне нужно включить ребра или мне нужно получить вершины классификации чертежей (промышленные, военные, жилые, коммерческие и т. д.). Фактически, чем больше связанных данных мне нужно получить для каждого проекта, тем более неряшливым становится мое решение.

Мой текущий запрос выглядит примерно так:

g.V().hasLabel("blueprint").as("blueprints").
outE().or(hasLabel("designed"),hasLabel("assisted")).inV().as("architects").
select("blueprints").coalesce(out("classification"),constant()).as("classifications").
select("blueprints","architects","classifications")

Вышеупомянутое приводит к большому дублированию. Если количество: blueprints равно b, архитекторов - a, а классификации - c, набор результатов будет содержать b * a * c результатов. Мне нужен один план с массивом связанных с ним архитекторов и массивом связанных с ним классификаций, если таковые имеются.

Осложнения

Я пытаюсь сделать это в одном запросе, чтобы получить все данные схемы из графика для заполнения отфильтрованного списка. Когда у меня есть список, содержащий все вершины, ребра и их свойства, пользователи могут щелкать ссылки на большие двоичные объекты, просматривать сайты проектов и т.д. предпочитаю совершать одну поездку на сервер каждый раз, когда я получаю новую страницу или меняются фильтры.


person Beans    schedule 23.10.2019    source источник
comment
вы можете добавить больше примеров своих данных, чтобы запрос стал более релевантным, например, вы, вероятно, ссылаетесь на industrial, military как на тип для blueprint, поэтому вы можете его расширить. Вы также можете предоставить пример запроса, чтобы другие не пошли по вашему пути.   -  person azbarcea    schedule 24.10.2019
comment
Я сделал, как и просили.   -  person Beans    schedule 24.10.2019
comment
Пожалуйста, проверьте свой скрипт загрузки данных. это неверный синтаксис. Наиболее заметные проблемы - это сочетание id в качестве ключа свойства с T.id, который представляет собой фактический идентификатор элемента графика. Кроме того, ваши addE() операторы неверны - модуляторы from() и to() должны указывать на метки шагов или вершину (в некоторых случаях последнее верно, но из-за проблемы T.id, о которой я упоминал, они не вернут вершину).   -  person stephen mallette    schedule 24.10.2019
comment
Я сделал, как просили.   -  person Beans    schedule 24.10.2019
comment
Не уверен, что это помогает добавить, что результат, который я ищу, представляет собой набор из трех кортежей, где для каждого кортежа: элемент 1 - это план, элемент 2 - это массив архитекторов проекта, а элемент 3 - это массив чертежа классификации.   -  person Beans    schedule 24.10.2019


Ответы (1)


Я придумал ответ; однако это в четыре раза увеличивает стоимость вычислений для запроса. Не уверен, что это можно оптимизировать дальше.

g.V().hasLabel("blueprint").
project("blueprints","architects").
by().
by(outE().or(hasLabel("designed"),hasLabel("assisted")).inV().dedup().fold())

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

Возможно, мне придется просто получить чертежи в одном запросе, получить каждый из связанных с ними элементов в параллельных запросах, а затем собрать все это вместе в API. Это было бы очень плохим дизайном для уровня данных API, но может быть необходимо по соображениям производительности.

person Beans    schedule 24.10.2019
comment
это outE().or(hasLabel("designed"),hasLabel("assisted")).inV() можно упростить до out('designed','assisted') - возможно, ваша база данных графиков не оптимизирует это or() должным образом - person stephen mallette; 25.10.2019
comment
Спасибо за предложение; однако это сокращает обработку всего на 0,4%. - person Beans; 25.10.2019
comment
не уверен, какую базу данных графов вы используете, но большинство графов не оптимизируют поиск вершин только по меткам. большинство графиков в конечном итоге будет выполнять полное сканирование графика, чтобы найти их. обычно обход начинается с вершины или небольшого подмножества вершин, идентифицированных индексом. Если вы выполняете полное сканирование графа и нужно найти множество вершин чертежа, для которых вам затем нужно пройти множество ребер, чтобы собрать все нужные данные, я думаю, я мог бы понять, почему это может быть медленным. - person stephen mallette; 25.10.2019
comment
Как упоминалось в сообщении, я использую упрощенную версию данных, что обязательно означает упрощенную версию запроса. Для выполнения проекта увеличьте количество вычислений в четыре раза (). - person Beans; 25.10.2019