Как я могу установить значения свойства списка в gremlin (CosmosDb) и спроецировать его в результат запроса? - PullRequest
0 голосов
/ 26 марта 2020

У меня есть вершина, у которой есть свойство списка, и я хочу заменить значения в указанном свойстве и спроецировать результат в указанном формате c. Для контекста, давайте предположим, что следующие данные:

g.AddV("Post").property("id", "1")
  .property(list, "Tags", "gremlin")
  .property(list, "Tags", "new")

Я хочу иметь возможность установить свойство Tags. То, что я пробовал до сих пор:

g.V("1")
  .sideEffect( properties("Tags").drop() )
  .property(list, "Tags", "gremlin")
  .property(list, "Tags", "closed")
  .property(list, "Tags", "solved")
  .project("Tags").By(values("Tags"))

Что я ожидал бы, это следующее

{
  "Tags": [
    "gremlin",
    "closed",
    "solved",
  ]
}

Но вместо этого я получаю ошибку Project By: Next: The provided traverser of key "Tags" maps to nothing. Так что, похоже, что Tags свойство было удалено полностью. Если после этого я сделаю запрос

g.V("1").project("Tags").By(values("Tags"))

, я получу ожидаемый результат:

{
  "Tags": [
    "gremlin",
    "closed",
    "solved",
  ]
}

Таким образом, данные должны быть изменены. Если я попробую без проецирования, результат будет содержать новые значения.

g.V("1")
  .sideEffect( properties("Tags").drop() )
  .property(list, "Tags", "gremlin")
  .property(list, "Tags", "closed")
  .property(list, "Tags", "solved")

В результате:

{
  "id": "1",
  "label": "Post",
  "type": "vertex",
  "properties": {
    "Tags": [
    {
      "id": "4eaf5599-511c-4245-aaf8-15c828073fac",
      "value": "gremlin"
    },
    {
      "id": "75e3ad96-a503-4608-a675-e28f3ffc2ab4",
      "value": "closed"
    },
    {
      "id": "aea1a33c-bd8e-47bb-b294-f01db8642db5",
      "value": "solved"
    },
    ]
  }
}

Но это не позволяет мне проецировать результат.

Как я могу как обновить данные, так и спроецировать их?

Другие вещи, которые я пробовал:

  • Добавление barrier() шаг после шага drop(), не работал
  • Добавление шага barrier() после шага sideEffect(), не работал
  • Добавление шага barrier() перед project() шаг, не работает
  • Выполнение того же, что и вышеупомянутые три, но вместо этого .fold().unfold() не сработало
  • Замена шага project() на optional(g.V("1").project("Tags").by(values("Tags"))) - этот работает путем повторного набора вершин, но стоит дорого.

1 Ответ

1 голос
/ 26 марта 2020

В этом случае с CosmosDB может что-то происходить, а это значит, что вам, возможно, придется получить от них конкретную c помощь. Обратите внимание, что ваш обход работает (почти так, как написано) с TinkerGraph, который является эталонной реализацией того, как Gremlin должен работать:

gremlin> g = TinkerFactory.createTheCrew().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:14], standard]
gremlin> g.V().has('person','name','marko').
......1>   sideEffect(properties("location").drop()).
......2>   property(list,'location','bombay').
......3>   property(list,'location','calcutta').
......4>   project('location').
......5>     by(values('location').fold())
==>[location:[bombay,calcutta]]

Возможно, вам следует попробовать свой запрос с моим by() модулятор на project(), чтобы увидеть, если добавленный fold() имеет какое-либо значение. Между прочим, я не ожидаю, что ваш обход без fold() вернет то, что вы говорите, оно возвращает. Обратите внимание, что происходит с TinkerGraph, если я попробую это:

gremlin> g.V().has('person','name','marko').
......1>   sideEffect(properties("location").drop()).
......2>   property(list,'location','bombay').
......3>   property(list,'location','calcutta').
......4>   project('location').
......5>     by(values('location'))
==>[location:bombay]

Замена шага project() на optional(g.V("1").project("Tags").by(values("Tags"))) - этот работает путем повторной загрузки вершины, но стоит дорого.

Вышеуказанное является интересным моментом, хотя у меня есть личная неприязнь к использованию g для порождения дочерних обходов, поэтому я предпочел бы анонимный обход, порожденный как optional(V("1").project("Tags").by(values("Tags"))). Это заставляет меня задуматься, не отражает ли CosmosDB мутации в текущем traverser, и именно поэтому вы получаете искомый результат при повторном запросе sh, выполняя повторный запрос. Я удивлен, что поиск в середине обхода обходится дорого, так как это поиск по элементу id и должен быть самым быстрым способом поиска вещей на графике. Тем не менее, это не так приятно, что вам приходится искать Vertex более одного раза в одном и том же обходе.

Из любопытства вы можете попробовать valueMap(true) вместо project() в качестве другого теста, просто чтобы посмотреть, вызывает ли это какое-либо другое поведение.

Еще одна вещь, которую можно попробовать, - использовать union() вместо sideEffect():

gremlin> g.V().has('person','name','marko').
......1>   union(properties("location").drop(), identity()).
......2>   property(list,'location','bombay').
......3>   property(list,'location','calcutta').
......4>   project('location').
......5>     by(values('location').fold())
==>[location:[bombay,calcutta]]

, чтобы увидеть, имеет ли это какое-либо значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...