3
votes

Here's a really simple query:

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

The JSON output of this is

{  
   "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":[  

         ]
      }
   }
}

Now, a customer vertex also contains the property name and age. What I would like to understand, is how to (simply, if possible) form my gremlin query such that it nests of the vertex properties within the graph. Note that when I just run g.V("customerId"), the response does contain these properties.

1

1 Answers

10
votes

You should always specific exactly the data that you want returned in a traversal. Even for something as simple as:

g.V('customerId')

you should really prefer:

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

It's really no different in SQL where you likely wouldn't do

SELECT * FROM customer

but instead

SELECT name, age FROM customer

As for your question, you just need to specify the data you want back, so use the by() modulator for the path():

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

That of course assumes your out() is also a "customer", if not, just add a second by() with the specific fields required for that. The by() modulators are applied in round-robin fashion. If you'd like a slightly cleaner bit of JSON to deal with you might instead use project() like:

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

as that will kill out the embedded lists that valueMap() adds in to properly account for multi-properties.

As of TinkerPop 3.4.4, you would also consider elementMap()-step which includes more of the structure of the graph element.

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]