Home > Back-end >  How do I obtain elementMaps of an edge and its two vertices in a single query?
How do I obtain elementMaps of an edge and its two vertices in a single query?

Time:11-25

Environment:

  • Node 16
  • Gremlin for node.js/Javascript
  • Amazon Neptune database

The goal is to list all edges between all vertices with one label and all vertices of another label, providing the elementMaps() of the vertices.

The following is the closest approximation I've achieved so far:

g.V().has('Customer', 'name', 'Customer').as('out').outE('HAS').as('edge').inV().hasLabel('Workstream').as('in').select('out', 'edge', 'in').toList()

This produces the following output (single item shown):

[{
    out: Vertex {
      id: 'bac24101-555a-e70b-66b1-434c5b2bb4fe',
      label: 'Customer',
      properties: undefined
    },
    edge: Edge {
      id: '74c24101-55a9-3421-029b-1ddd68178cfd',
      label: 'HAS',
      outV: [Vertex],
      inV: [Vertex],
      properties: {}
    },
    in: Vertex {
      id: 'b8c24101-5548-f39e-70c9-a9bd126e05b2',
      label: 'Workstream',
      properties: undefined
    }
 }]

This does not give me the elementMap of the edge or the vertices, but it is a format I can consume. The desired output is:

[{
    edge: {
      elementMapOfEdge,
      outV: { elementMapOfOutVertex },
      inV: { elementMapOfInVertex },
     }
 }]

Note that

g.V().has('Customer', 'name', 'Customer').dedup().by('name').outE('HAS').as('edge').inV().hasLabel('Workstream').select('edge').elementMap().toList()

Gives me the elementMap of the edge but not the incoming or outgoing vertices. The dedup() step addresses duplicate names in the vertices which is a data hygiene issue at this time.

Curiously the elementMapping of the edge changes the vertex labels from 'outV' and 'inV' to 'OUT' and 'IN' -- I assume because the values are no longer Vertex objects but plain JS objects.

With respect to step labels, etc., I am more concerned with function than style. The goal is to achieve the desired result, rather than to be perfectly idiomatic with Gremlin at this point -- though it would be great to accomplish both!

CodePudding user response:

This may not be exactly the format you're looking for, but it is close. There maybe some additional massaging with the list of maps to merge those into a single map, but getting there may not be entirely necessary depending on how you're consuming this data within your application:

g.V().has('Customer', 'name', 'Customer').dedup().by('name').
    outE('HAS').as('edge').inV().hasLabel('Workstream').select('edge').
    project('edge').
    by(
        union(
            elementMap(),
            project('outV','inV').
                by(outV().elementMap()).
                by(inV().elementMap())
        ).fold()).toList()
  • Related