Как я могу вернуть значимые ошибки в Gremlin? - PullRequest
0 голосов
/ 12 декабря 2018

Допустим, у меня есть огромный запрос gremlin с 100 или более шагами.Одна часть этого запроса имеет сбой, и я хочу, чтобы он возвращал значимое сообщение об ошибке.С коротким и приятным запросом это не будет слишком сложно, поскольку мы можем сделать что-то вроде этого:

g.V().coalesce(hasId("123"), constant("ERROR - ID does not exist"))

Конечно, мы спрашиваем, существует ли вершина с идентификатором 123.Если он не существует, мы возвращаем строку.

Итак, давайте возьмем этот пример и сделаем его более сложным

g.V().coalesce(hasId("123"), constant("ERROR - ID does not exist")).as("a").V().coalesce(hasId("123"), constant("ERROR - ID does not exist")).as("b").select("a").valueMap(false)

Если существует вершина с идентификатором: «123», мы возвращаем все свойствахранится в вершине.

Допустим, вершина с идентификатором: «123» не существует в базе данных.Как я могу получить значимую ошибку, возвращаемую без ошибки типа при попытке сделать .valueMap () для строки?

1 Ответ

0 голосов
/ 12 декабря 2018

Прежде всего, если у вас есть одна строка Gremlin с 100 или более шагами (конечно, не считая шагов анонимных дочерних переходов), я бы посоветовал вам пересмотреть свой подход в целом.Когда я сталкиваюсь с Гремлином такого размера, это обычно означает, что кто-то генерирует большой обход для того, чтобы каким-то образом поменять график.Это считается анти-паттерном, и его следует избегать, так как чем больше растет Gremlin, тем выше вероятность достижения пределов Xss JVM для StackOverflowException, а время прохождения компиляции, как правило, увеличивается и становится дорогим.Во многих случаях всего этого можно избежать, если каким-либо образом использовать inject() или withSideEffect() для передачи данных самого обхода, а затем использовать Gremlin в качестве цикла, который превращает эти данные в этапы мутации.В результате получается несколько более сложный оператор Gremlin, но он будет работать лучше и позволит избежать StackOverflowException.

Во-вторых, обратите внимание, что этот обход, скорее всего, не будет работать так, как вы хотите, в любом поставщике графов - см. Этот примерна TinkerGraph:

gremlin> g.V().coalesce(hasId(1),constant('x'))
==>v[1]
==>x
==>x
==>x
==>x
==>x
gremlin> g.V().hasId(1)
==>v[1]

hasId() внутри coalesce() не будет оптимизирован графиком как быстрый поиск id, а вместо этого будет рассматриваться как полное сканирование таблицы с фильтром.

В ответ на ваш вопрос я бы сказал, что самый простой вариант для вас - просто переместить valueMap() внутрь coalesce():

g.V().coalesce(hasId("123").valueMap(false), 
               constant("ERROR - ID does not exist")).as("a").
  V().coalesce(hasId("123").valueMap(false), 
               constant("ERROR - ID does not exist")).as("b").
  select("a")

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

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

gremlin> g.V(1).fold().coalesce(unfold(),map{throw new IllegalStateException("bad")})
==>v[1]
gremlin> g.V(10).fold().coalesce(unfold(),map{throw new IllegalStateException("bad")})
bad

В настоящее время я не уверен, что вы можете сделать что-то еще.Возможно, вы могли бы сделать «ошибку» Vertex, которую вы могли бы вернуть в constant() таким образом, valueMap() сработало бы, но трудно сказать, будет ли это полезно, учитывая то, что я знаю об общем намерении вашего обхода.Я полагаю, вы могли бы придумать причудливую оценку «если-тогда», используя choose(), но это может быть трудно читать и выглядеть неловко.Единственный другой вариант, который я могу придумать, - сохранить ошибку как побочный эффект:

gremlin> g.V(10).fold().coalesce(unfold(),store('error').by(constant('x'))).cap('error')
==>[x]

Я не думаю, что Гремлин дает вам действительно элегантный способ сделать то, что вы хотите прямо сейчас.

...