gremlinamazon-neptunegremlinpython

How to get an AWS Neptune gremlin query to filter by pricing_id


I have a working query using gremlin_python that looks like the following (simplified to focus on the issue)

client.graph.V().as_('origin') \
        .outE().as_('p1r1') \
        .inV().as_('midpoint') \
        .outE().has('pricing_id', select('p1r1').pricing_id).as_('p1r2') 
        .inV().

So in this, I have 2 edges (p1r1 and p1r2) and I'm just checking that a value of p1r1 is equal to the same value of p1r2.

How can I rewrite this in gremlin to allow for that? So far I have the following but I can't get the select('p1r1').pricing_id to work. It doesn't like the ".pricing_id" part of the notation.

"gremlin" :"g.V().as('origin') \
            .outE().as('p1r1') \
            .inV().as('midpoint') \
            .outE().has('pricing_id', select('p1r1').pricing_id).as('p1r2') 
            .inV().

For reference I'm sending this through the gremlin API for AWS Neptune.

Thank you in advance.


Solution

  • Currently, while it is something that can hopefully be addressed in the future, Apache TinkerPop Gremlin does not allow for queries of the form:

    has(key,<some-traversal>)
    

    All that is allowed is:

    has(key,<P predicate>)
    

    For example:

    has(key,eq('123ABC'))
    

    If you try something like:

    has(key,select('x'))
    

    the query will not always error out, depending on how you issue it (text vs bytecode), but it will never do what it looks like it should.

    The query needs to be rewritten to use the where...by syntax.

    For example, in your specific case:

    outE().as('x').
    where(eq('x')).
      by('pricing_id').
      by(select('p1r1').values('pricing_id')) 
    

    Edited 2023-03-03 To show why has(key,select()) does not work.

    Consider the example below. The values 1 and 2 are clearly not the same. However, as select('x') returns something, as far as the has step is aware, that is treated as a match. This is something that hopefully will be improved in a future TinkerPop release. Until that time, the best way to do these types of operations, is using the where...by syntax.

    gremlin> g.V(3).values('runways')
    ==>2
    gremlin> g.inject(1).as('x').V(3).has('runways',select('x'))
    ==>v[3]