Is there an equivalent of a left join in Apache TinkerPop's Gremlin language?

Viewed 48

I'm new to Gremlin and Apache TinkerPop, and so this hopefully should be something simple. I have a graph where a role relationship is made between a vertex with a label of person and another with a label of authority. The edges have labels reflecting the role, e.g. adminsters, reads etc.

The authority vertices also nest, and so have edges between themselves of owns. In the permission model, this should be being used to apply implicit permissions, so if you have the adminsters relationship to a top level authority it should also apply to all the authorities that authority owns.

Some sample to set something basic up:-


g.addV('person').property('name', 'dan').as('dan')
    .addV('person').property('name', 'mike').as('mike')
    .addV('person').property('name', 'saikiran').as('saikiran')
    .addV('authority').property('name', 'My Office Global').as('mo_global')
    .addV('authority').property('name', 'My Office EU').as('mo_eu')
    .addV('authority').property('name', 'My Office ANZ').as('mo_anz')
    .addV('authority').property('name', 'My Office UK').as('mo_uk')
    .addV('authority').property('name', 'My Office Germany').as('mo_germany')
    .addE('owns').from('mo_global').to('mo_eu')
    .addE('owns').from('mo_global').to('mo_anz')
    .addE('owns').from('mo_eu').to('mo_uk')
    .addE('owns').from('mo_eu').to('mo_germany')
    .addE('administers').from('dan').to('mo_eu')
    .addE('reads').from('dan').to('mo_global')
    .addE('administers').from('mike').to('mo_uk')
    .addE('reads').from('mike').to('mo_eu')
    .addE('administers').from('saikiran').to('mo_anz')

From this I want to create a query that gets all the authorities and their children that a user has the administers relationship with; the query I currently have is below:-

g.V().hasLabel('person').as('person')
    .out('administers').as('admin_role')
    .repeat(out('owns').as('auth_child'))
    .emit()
    .select('person').values('name').as('person_name')
    .select('admin_role').values('name').as('explicit_admin_role')
    .select('auth_child').values('name').as('implicit_admin_role')
    .select('person_name', 'explicit_admin_role', 'implicit_admin_role')

The issue I have is that this works for the person where there are children of the authority, but I lose those people who are administrators of a bottom level authority.

Coming from a SQL background, I'd want to make the repeat(out..) some kind of left join, but I'm not sure who to do this, or if it's possible, in Gremlin?

Thank you in advance.

1 Answers

Ok managed to get what I needed done using projects:-

g.V().hasLabel('person').as('person')
    .project('user', 'explicit', 'implicit')
    .by('name')
    .by(out('administers').values("name"))
    .by(out('administers')
        .repeat(out('owns').as('implicit'))
        .emit()
        .select('implicit').values('name')
        .fold())
Related