ArobTheArab
ArobTheArab

Reputation: 65

How do I obtain elementMaps of an edge and its two vertices in a single query?

Environment:

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!

Upvotes: 0

Views: 120

Answers (2)

ArobTheArab
ArobTheArab

Reputation: 65

Following the example provided by Taylor Riggan I came up with a similar answer that performs the massaging to which he referred and generates exactly the structure I want:

g.V().hasLabel('User').as('in').outE().as('edge').inV().as('out').select('in', 'edge', 'out').by(wsx.__.elementMap()).by(wsx.__.elementMap()).by(wsx.__.elementMap()).toList()

Note that wsx.__ maps to gremlin.process.statics in JS Gremlin library.

This generates an output structure that looks like this:

[
  {
    in: {
      id: '[email protected]',
      label: 'User',
      name: 'Test User'
    },
    edge: {
      id: '1cc25300-3a47-8aef-6b40-017ab8592910',
      label: 'ADMINISTRATOR',
      IN: [Object],
      OUT: [Object],
      description: 'Workstream Administrator'
    },
    out: {
      id: '9ec25300-23cb-b316-f893-9f7a37ca4330',
      label: 'Workstream',
      name: 'Test 4',
      description: 'test 4 WS'
    }
  }
]

Upvotes: 0

Taylor Riggan
Taylor Riggan

Reputation: 2759

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()

Upvotes: 1

Related Questions