Как собрать все свойства вершин и ребер вдоль пути с помощью Gremlin

Вот действительно простой запрос:

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

Результатом этого JSON является

{  
   "requestId":"96b26c1d-d032-2004-d36e-c700bd6db2a2",
   "status":{  
      "message":"",
      "code":200,
      "attributes":{  
         "@type":"g:Map",
         "@value":[  

         ]
      }
   },
   "result":{  
      "data":{  
         "@type":"g:List",
         "@value":[  
            {  
               "@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":"customerId",
                              "label":"customer"
                           }
                        },
                        {  
                           "@type":"g:Vertex",
                           "@value":{  
                              "id":"e:[email protected]",
                              "label":"email"
                           }
                        }
                     ]
                  }
               }
            }
         ]
      },
      "meta":{  
         "@type":"g:Map",
         "@value":[  

         ]
      }
   }
}

Теперь вершина клиента также содержит имя свойства и возраст. Я хотел бы понять, как (просто, если возможно) сформировать мой запрос гремлина таким образом, чтобы он вмещал свойства вершины в графе. Обратите внимание, что когда я просто запускаю g.V ("customerId"), ответ действительно содержит эти свойства.


person Wendell Blatt    schedule 26.07.2018    source источник


Ответы (1)


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

g.V('customerId')

вам действительно стоит предпочесть:

g.V('customerId').valueMap('name','age')

На самом деле это ничем не отличается в SQL, где вы, вероятно, не сделаете этого

SELECT * FROM customer

но вместо того, чтобы

SELECT name, age FROM customer

Что касается вашего вопроса, вам просто нужно указать данные, которые вы хотите вернуть, поэтому используйте модулятор by() для path():

g.V('customerId').
  out().
  path().
    by(valueMap('name','age'))

Это, конечно, предполагает, что ваш out() также является «клиентом», в противном случае просто добавьте второй by() с конкретными полями, необходимыми для этого. Модуляторы by() применяются циклически. Если вам нужен более чистый бит JSON, вы можете вместо этого использовать project(), например:

g.V('customerId').
  out().
  path().
    by(project('name','age').
         by('name').
         by('age'))

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

Начиная с TinkerPop 3.4.4, вы также можете рассмотреть elementMap()-step, который включает в себя большую часть структуры элемента графика.

gremlin> g.V().has('person','name','marko').elementMap()
==>[id:1,label:person,name:marko,age:29]
gremlin> g.V().has('person','name','marko').elementMap('name')
==>[id:1,label:person,name:marko]
gremlin> g.V().has('person','name','marko').properties('name').elementMap()
==>[id:0,key:name,value:marko]
gremlin> g.E(11).elementMap()
==>[id:11,label:created,IN:[id:3,label:software],OUT:[id:4,label:person],weight:0.4]
person stephen mallette    schedule 26.07.2018
comment
Есть ли способ включить эти данные в тип вершины или ребра в gList? Добавления запросов, которые вы мне дали, возвращают все в g: Map s. Мы надеемся на некоторую однородность данных, чтобы мы могли иметь некоторую согласованность в наших выводах и, следовательно, демаршалинг DRY JSON. - person Wendell Blatt; 26.07.2018
comment
При возврате данных следует обращаться к стандартным коллекциям. Это восходит к моей точке зрения о том, что вы должны явно указать, что вы возвращаете. Не существует частичной концепции элемента графа (т.е. возврата Vertex только с некоторыми свойствами), и, как вы видели в своем запросе, мы отделим эту вершину, чтобы все, что вы получили, это идентификатор / метка. мы называем эту форму вершины опорной вершиной, и в будущем все это TinkerPop будет возвращать для всех обходов (уже так работает в некоторых реализациях графов и сериализаторах TinkerPop). - person stephen mallette; 27.07.2018
comment
Если вам интересно, почему мы считаем полные вершины плохими, вы должны учитывать множественные свойства. Представьте себе вершину с миллионом свойств на ней, и вы случайно вернете это нефильтрованное в path() - это будет дорогостоящий день сериализации, чтобы вернуть этот результат. - person stephen mallette; 27.07.2018
comment
Хорошо. справедливо. Я ценю, что вы мне это объяснили. Еще один вопрос: как мне добавить идентификатор вершины в проект (...)? Я попытался просто добавить идентификатор аргумента, но, похоже, это не сработало. Основываясь на нашей реализации, довольно просто демаршалировать карту в свойствах вершин, но без первичного ключа я не могу определить вершину, на которую ссылаются сопоставленные атрибуты. - person Wendell Blatt; 27.07.2018
comment
это просто by(T.id) или просто by(id), если T статически импортирован - person stephen mallette; 27.07.2018