Search code examples
gremlingraph-databasesamazon-neptune

How to short-circuit a where statement in Gremlin?


I am wondering if it is possible to short-circuit a where statement when finding the first result.

Here is a sample query:

g.V().hasLabel('SEAT')
    where(
        __.repeat(out('NEXT').simplePath())
        .until(loops().is(gte(2)))
    )
    .in('CONTAINS')
    .dedup()

The de-dupe is required because there could be multiple lengths from a given vertex that have a parent on the in edge of 'CONTAINS' which has chains of vertices on the out edge of 'NEXT'.

What I would like is to short-circuit the where on finding the first time a vertex satisfies the criteria.

Here is a sample graph and query: https://gremlify.com/bwa7spaz97b/5

More clarification on the issue:

If I change the query to use path instead of dedup the results are as follows:

[
  [
    {
      "id": 15245,
      "label": "SEAT"
    },
    {
      "id": 15239,
      "label": "SECTION"
    }
  ],
  [
    {
      "id": 15248,
      "label": "SEAT"
    },
    {
      "id": 15239,
      "label": "SECTION"
    }
  ],
  [
    {
      "id": 15257,
      "label": "SEAT"
    },
    {
      "id": 15242,
      "label": "SECTION"
    }
  ],
  [
    {
      "id": 15260,
      "label": "SEAT"
    },
    {
      "id": 15242,
      "label": "SECTION"
    }
  ],
  [
    {
      "id": 15263,
      "label": "SEAT"
    },
    {
      "id": 15242,
      "label": "SECTION"
    }
  ]
]

You can notice that there is a result (child vertex start + parent vertex) for each path that satisfies the where condition (ie. Multiple results with the same SECTION vertex). I want the query to stop processing once it finds the first path that satisfies the where clause.

Fundamentally, I want to find each 'SECTION' vertex where there is a path of length N or greater on its child vertices.

The result I'm looking for (using path) would look something like this:

[
  [
    {
      "id": 15245,
      "label": "SEAT"
    },
    {
      "id": 15239,
      "label": "SECTION"
    }
  ]
  [
    {
      "id": 15257,
      "label": "SEAT"
    },
    {
      "id": 15242,
      "label": "SECTION"
    }
  ]
]

I'm essentially looking for something like whereFirst (if it actually existed).


Solution

  • You can rewrite the query as follows to filter out duplicates inside the where

    g.V().hasLabel('SEAT').
        where(
            __.repeat(out('NEXT').simplePath().where(without('x')).store('x'))
            .until(loops().is(gte(2)))
        )
        .in('CONTAINS')