Search code examples
gremlinazure-cosmosdb-gremlinapi

Unpack vertices' properties returned from a select()


I would like to write a MATCH query in gremlin to find a subgraph matching a particular pattern. The pattern of interest contains 4 different types/labels of nodes: c, p, r, and s. And 4 different types of edges as shown below:

(c)->[affecting]->(p)
(c)-[c_found_in_release]->(r)
(p)-[p_found_in_release]->(r)
(s)-[severity]->(c)

So far I have the query below which works fine, however, the results do not show the properties of the vertices returned. Since the verticies returned from the select() statement belong to different types of nodes, I cannot use something like value() or valueMap()

    g.V().match(
            __.as('c').out('affecting').as('p'), \
            __.as('c').out('cve_found_in_release').as('r'), \
            __.as('p').out('pack_found_in_release').as('r'), \
            __.as('s').both('severity').as('c') \
    ). \
    select('c', 'p', 'r', 's').limit(10)
  • Current result:
    ==>[c:v[0],p:v[3],r:v[6],s:v[10]]
    

How to get something more detailed like this instead:

  • Desired result:
==>[
        c:[cve_id:[CVE-2021-3618],publishedOn:[2022-03-23],
        p:[name:[vsftpd],version:[3.0.3]],
        r:[sourceBranch:[1.0],detectedOn:[2022-04-05],status:[Upgraded]],
        s:[severity:[High]],
    ]

Solution

  • You can simply add additional by() modulators. On the Tinkergraph modern example graph:

    g = TinkerFactory.createModern().traversal()
    g.V().match(
      __.as('v').hasLabel('software').as('s'),
      __.as('s').both().hasLabel('person').as('p')
    ).select('s', 'p')
      .by(values('name', 'lang').fold())
      .by(values('name', 'age').fold())
    ==>[s:[lop,java],p:[marko,29]]
    ==>[s:[lop,java],p:[josh,32]]
    ==>[s:[lop,java],p:[peter,35]]
    ==>[s:[ripple,java],p:[josh,32]]