Как мне произвести вывод, даже если нет края и при использовании выбора для проекции

Может кто-нибудь помочь мне с этим простым запросом... Большое спасибо заранее...

Я использую следующий запрос гремлина, и он хорошо работает, предоставляя мне исходную вершину (v) (с id-=12345), ее ребра (e) и дочернюю вершину (свойство id). Однако, скажем, если исходная вершина 'v' (с id-12345) не имеет исходящих ребер, запрос ничего не возвращает. Мне все еще нужны свойства исходной вершины ('v'), даже если у нее нет исходящих ребер и дочерних элементов. Как я могу это сделать?

g.V().has('id', '12345').as('v').
  outE().as('e').
  inV().
    as('child_v').
    select('v', 'e', 'child_v').
    by(valueMap()).by(id).by(id)

person nDev    schedule 18.05.2020    source источник


Ответы (2)


Здесь происходит несколько вещей, но основное обновление, которое вам нужно для обхода, — это использование шага project() вместо select().

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

В вашем исходном обходе, когда нет исходящих ребер из исходного v, поэтому все обходчики отфильтровываются во время шага outE(). Поскольку после шага outE() нет дальнейших обходов, оставшаяся часть обхода не имеет входного потока, поэтому нет данных для возврата. Если вы используете шаг project() после исходного v, вы можете вернуть исходный обходчик, а также вернуть ребра и инцидентную вершину. Это приводит к небольшому усложнению при обработке случаев, когда внешних краев не существует. Gremlin не обрабатывает нулевые значения, такие как отсутствие внешних границ, вам необходимо вернуть некоторое постоянное значение для этих операторов с помощью оператора объединения.

Вот действующая версия этого обхода:

g.V().hasId(3).
  project('v', 'e', 'child_v').
    by(valueMap()).
    by(coalesce(outE().id(), constant(''))).
    by(coalesce(out().id(), constant(''))) 
person bechbd    schedule 18.05.2020
comment
Отличное объяснение проблемы, но исходный запрос имел связь между идентификатором ребра и дочерним идентификатором. В заданном вами запросе будет возвращено только одно ребро и один дочерний элемент. И даже если вы добавите fold, вы получите два отдельных массива. - person noam621; 18.05.2020
comment
Я не уверен @noam621, что вы имеете в виду, когда говорите только об одном крае и одном ребенке. Ваши запросы (оба), а также выше, используют outE(). Я понял, что если из родительской вершины 5 ребер, эти запросы вернут родительские свойства, идентификатор ребра и идентификатор вершины для каждой из дочерних вершин (т.е. 5). Это то, что outE() дает вам AFAIK... спасибо - person nDev; 18.05.2020
comment
@nDev Шаг by останавливается при первом обходе, который возвращает значение, поэтому, если вы не используете шаг fold внутри каждого by, даже если есть 5 ребер, будет возвращено только одно - person noam621; 18.05.2020
comment
@nDev Посмотрите разницу между случаями: gremlify.com/a4 - person noam621; 18.05.2020
comment
Хорошо, насколько я понимаю, by(coalesce(...)) остановится после первого ребра, поэтому он не будет проходить через другие ребра. В таком случае, какой правильный запрос использовать из 3 (ваш второй запрос также не использует fold())? Я пытался получить родительскую вершину (ее свойства) и все ее ребра (свойства) и дочерние элементы (свойства)... если между родителем и дочерним элементом нет края, то он вернет родителя и, возможно, пустую строку или что-то в этом роде. для краевых и дочерних свойств (как показано @bechbd - person nDev; 18.05.2020
comment
Хорошо, кажется, я понимаю, что вы сейчас ищете. Вы можете сделать это, используя необязательный () шаг. Посмотрите здесь: gremlify.com/a7 - person bechbd; 18.05.2020
comment
@nDev Я думаю, что мой первый запрос, вероятно, сработает лучше всего. избегая выборки повторяющихся данных и получая идентификатор ребра и дочерний идентификатор в одной структуре - person noam621; 18.05.2020
comment
@ noam621 Ваш первый запрос дает результаты, но только если есть преимущество от Node. Я хотел родительскую вершину, даже если между родителем и дочерним элементом нет края. Первый запрос мне ничего не дает. Запрос, который дал bechbd, работает хорошо во всех случаях. - person nDev; 19.05.2020
comment
@nDev Запрос в a7 будет работать отлично и намного элегантнее, чем мой второй запрос ... но все равно будет получать много повторяющихся данных. первый запрос должен работать, даже если нет дочерних вершин или я что-то упустил? gremlify.com/aa - person noam621; 19.05.2020
comment
Я не уверен, какие повторяющиеся данные вы имеете в виду? Я попробовал это, и, похоже, дубликаты данных не возвращаются. Запрос в a7, похоже, работает, даже если между родителем и дочерним элементом нет границы, и возвращает только родитель, как я и хотел. Это потому, что он использует необязательный. Спасибо @bechd! Вы оба дали мне отличные вопросы для работы с дальнейшим пониманием Gremlin QL. Очень признателен. Не могли бы вы оба обновить свои запросы выше, чтобы отразить то, что я сказал. Только для использования другими людьми в будущем! - person nDev; 19.05.2020
comment
@nDev Я имел в виду, что свойства вершины будут возвращены для каждого дочернего элемента. если у Марко есть 5 вершин, связанных с ним, вы получите valueMap Марко 5 раз... - person noam621; 19.05.2020
comment
@ noam621 и bechbd, что-то странное при возврате значений во всех ваших запросах. Допустим, у нас есть A, у которого есть два ребенка B и C. И у C есть D как один ребенок. Когда я запрашиваю A, я получаю список по одному для каждого из двух ребер. Когда я запрашиваю, скажем, B, C или D, я получаю список, содержащий родительскую вершину или родительскую вершину, ребро и идентификатор дочерней вершины. Выход разный. Я хочу последовательное возвращаемое значение, где я бы получил список независимо. и каждый элемент в списке будет словарем, содержащим родительскую вершину, ребро и идентификатор дочерней вершины. Как и в случае, когда я запрашиваю вершину A. - person nDev; 19.05.2020
comment
Давайте продолжим обсуждение в чате. - person noam621; 19.05.2020

В настоящее время вы получите много повторяющихся данных, в приведенном выше запросе вы получите свойства вершины E раз. вероятно, будет лучше использовать project:

g.V('12345').project('v', 'children').
    by(valueMap()).
    by(outE().as('e').
      inV().as('child').
        select('e', 'child').by(id).fold())

пример: https://gremlify.com/a1

Вы можете получить исходный формат данных, если сделаете что-то вроде этого:

g.V('12345').as('v').
  coalesce(
    outE().as('e').
    inV().
      as('child_v')
    select('v', 'e', 'child_v').
    by(valueMap()).by(id).by(id),
    project('v').by(valueMap())
  )

пример: https://gremlify.com/a2

person noam621    schedule 18.05.2020