Почему функция Gremlin fold () влияет на результат ответа JSON?

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

Так почему это происходит?

g.V('1').out().path()

g.V('1').out().path().by(unfold().fold())

Когда я запускаю следующий запрос: g.V('1').out().path()

{
...
    {
      "@type": "g:Path",
      "@value": {
        "labels": {
          "@type": "g:List",
          "@value": [
            {
              "@type": "g:Set",
              "@value": []
            },
            {
              "@type": "g:Set",
              "@value": []
            }
          ]
        },
        "objects": {
          "@type": "g:List",
          "@value": [
            {
              "@type": "g:Vertex",
              "@value": {
                "id": "1",
                "label": "USER"
              }
            },
            {
              "@type": "g:Vertex",
              "@value": {
                "id": "2",
                "label": "USER"
              }
            }
          ]
        }
      }
    }
...
}

Но когда я g.V('1').out().path().by(unfold().fold())

{
...
  {
    "@type": "g:Path",
    "@value": {
      "labels": {
        "@type": "g:List",
        "@value": [
          {
            "@type": "g:Set",
            "@value": []
          },
          {
            "@type": "g:Set",
            "@value": []
          }
        ]
      },
      "objects": {
        "@type": "g:List",
        "@value": [
          {
            "@type": "g:List",
            "@value": [
              {
                "@type": "g:Vertex",
                "@value": {
                  "id": "1",
                  "label": "USER",
                  "properties": {
                    "prop1": [
                      {
                        "@type": "g:VertexProperty",
                        "@value": {
                          "id": {
                            "@type": "g:Int32",
                            "@value": 101839172
                          },
                          "value": {
                            "@type": "g:Int32",
                            "@value": 1
                          },
                          "label": "prop1"
                        }
                      }
                    ],
                    "created_at": [
                      {
                        "@type": "g:VertexProperty",
                        "@value": {
                          "id": {
                            "@type": "g:Int32",
                            "@value": 589742877
                          },
                          "value": {
                            "@type": "g:Date",
                            "@value": 1557226436119
                          },
                          "label": "created_at"
                        }
                      }
                    ]
                  }
                }
              }
            ]
          },
          {
            "@type": "g:List",
            "@value": [
              {
                "@type": "g:Vertex",
                "@value": {
                  "id": "2",
                  "label": "USER",
                  "properties": {
                    "prop1": [
                      {
                        "@type": "g:VertexProperty",
                        "@value": {
                          "id": {
                            "@type": "g:Int32",
                            "@value": -1354828672
                          },
                          "value": {
                            "@type": "g:Date",
                            "@value": 1557225020168
                          },
                          "label": "prop1"
                        }
                      }
                    ],
                    "created_at": [
                      {
                        "@type": "g:VertexProperty",
                        "@value": {
                          "id": {
                            "@type": "g:Int32",
                            "@value": 589742878
                          },
                          "value": {
                            "@type": "g:Date",
                            "@value": 1557226436119
                          },
                          "label": "created_at"
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        ]
      }
    }
  }
...
}

РЕДАКТИРОВАТЬ: Дополнительная информация. Я обнаружил, что в дополнение к fold() я могу получить всю сущность со свойствами, используя project() и identity().

Поэтому, когда я запускаю g.V('1').out().path().by(identity()), я получаю следующее содержимое Пути, такое же, как и в первом запросе.

      "objects": {
        "@type": "g:List",
        "@value": [
        {
          "@type": "g:Vertex",
          "@value": {
            "id": "1",
            "label": "USER"
        }
        },
        {
          "@type": "g:Vertex",
          "@value": {
            "id": "2",
            "label": "USER"
        }
    }
  ]
}

Но когда я запускаю g.V('1').out().path().by(project('identity').by(identity())), в пути я получаю следующее (обратите внимание на объект свойств):

"objects": {
    "@type": "g:List",
    "@value": [
        {
            "@type": "g:Map",
            "@value": [
                "identity",
                {
                    "@type": "g:Vertex",
                    "@value": {
                        "id": "1",
                        "label": "USER",
                        "properties": {
                            "prop1": [
                                {
                                    "@type": "g:VertexProperty",
                                    "@value": {
                                        "id": {
                                            "@type": "g:Int32",
                                            "@value": 101839172
                                        },
                                        "value": {
                                            "@type": "g:Int32",
                                            "@value": 1
                                        },
                                        "label": "prop1"
                                    }
                                }
                            ],
                            "created_at": [
                                {
                                    "@type": "g:VertexProperty",
                                    "@value": {
                                        "id": {
                                            "@type": "g:Int32",
                                            "@value": 589742877
                                        },
                                        "value": {
                                            "@type": "g:Date",
                                            "@value": 1557226436119
                                        },
                                        "label": "created_at"
                                    }
                                }
                            ],
                        }
                    }
                }
            ]
        }

person Vasar    schedule 08.05.2019    source источник
comment
интересно - какую базу данных графов вы используете?   -  person stephen mallette    schedule 08.05.2019
comment
Я использую Neptune, так что думаю, это своего рода черный ящик, как именно они реализовали гремлин.   -  person Vasar    schedule 09.05.2019
comment
На самом деле шаг unfold() не нужен, это шаг fold(), который в основном добавляет свойства ребрам и вершинам. Полагаю, это ненормальное поведение Гремлина? Есть ли способ получить всю вершину / ребро, не выполняя fold()?   -  person Vasar    schedule 09.05.2019


Ответы (1)


Вы никогда не должны получать свойства ни одного элемента графика (например, Vertex, Edge или VertexProperty), возвращенного с сервера - только «ссылку», состоящую из id и label. Итак, то, что вы видите в первом обходе, правильно, а то, что вы видите во втором, где используется by(unfold().fold()), неверно.

На самом деле это ошибка в TinkerPop, для которой я создал TINKERPOP-2212. .

Правильный способ получить то, что вы хотите, - это сделать что-то вроде:

gremlin> g.V(1).out().path().by(valueMap())
==>[[name:[marko],age:[29]],[name:[lop],lang:[java]]]
==>[[name:[marko],age:[29]],[name:[vadas],age:[27]]]
==>[[name:[marko],age:[29]],[name:[josh],age:[32]]]
gremlin> g.V(1).out().path().by(valueMap(true).by(unfold()))
==>[[id:1,label:person,name:marko,age:29],[id:3,label:software,name:lop,lang:java]]
==>[[id:1,label:person,name:marko,age:29],[id:2,label:person,name:vadas,age:27]]
==>[[id:1,label:person,name:marko,age:29],[id:4,label:person,name:josh,age:32]]

или, возможно, в последних версиях TinkerPop замените valueMap(true) на:

gremlin> g.V(1).out().path().by(valueMap().by(unfold()).with(WithOptions.tokens))
==>[[id:1,label:person,name:marko,age:29],[id:3,label:software,name:lop,lang:java]]
==>[[id:1,label:person,name:marko,age:29],[id:2,label:person,name:vadas,age:27]]
==>[[id:1,label:person,name:marko,age:29],[id:4,label:person,name:josh,age:32]]
person stephen mallette    schedule 09.05.2019
comment
Хорошо, мне было интересно, было ли это так задумано. Хотя почему бы не предоставить свойства, например, с каким-либо аргументом, который также загружал бы свойства. Я просто думаю, что если бы у меня был клиент для Gremlin, я мог бы определить структуру данных, которая имела бы идентификатор, метку и свойства, чтобы взаимодействие с данными было более согласованным? - person Vasar; 09.05.2019
comment
Существует ряд причин для возврата ссылочного элемента без свойств, но одна из основных заключается в том, что существует риск тяжелой вершины - вершины с тонной данных свойств, которая потребовала бы огромного количества ресурсов сервера для сериализации. . Потенциал этой ситуации обусловлен поддержкой TinkerPop нескольких свойств - представьте себе вершину с более чем миллионом свойств на ней, вы делаете g.V() и в конечном итоге попадаете в нее (или, что еще хуже, несколько из них). Не возвращая свойства и заставляя пользователей явно указывать, что они возвращают, мы смягчаем эту проблему. - person stephen mallette; 09.05.2019
comment
Я всегда сравниваю эту проблему с SQL, где вы никогда не сделаете SELECT * FROM table - вы должны указать точные поля, которые нужно вернуть, потому что, если ваша схема когда-либо была изменена и добавлена, например, поле blob, вы внезапно выберете и эти данные, которые могут не быть таким хорошим для вашего приложения. - person stephen mallette; 09.05.2019
comment
Да, я понимаю, почему это поведение по умолчанию, но было бы неплохо иметь выбор, как в SQL. - person Vasar; 09.05.2019