Search code examples
javascriptnode.jsazure-cosmosdbgremlintinkerpop

How to return all steps of traversal even if Gremlin query can not complete?


My problem is the following:

I have a graph containing vertices labeled as 'user' and edges between them that corresponds to their family relationship. The two types of vertices are parent users and child users. The edge labels between them are 'childOf' and 'parentOf'. A parent can have multiple children but for simplicity's sake a child can only have one parent. I want to create a Gremlin query that gets all the children of a specific parent. I'm using CosmosDB and Node.js, so the query looks like this:

(`g.V().has('userId', userId).has('isParent', isParent).outE('parentOf').inV().path()`, {
   userId: userId,
   isParent: true
})

This does work, and gets all of the child users. I can parse the result, and get everything I want in the scenarion when the parent user does exist, and it has one or more children.

But what about the scenario when the parent does not have any children, or when the parent does not even exist? This is why I started to use the 'path()' flag at the end of the query. If there is a parent, and it does have a child, this query has three steps through the traversal. The first is going to the parent vertex, the second is going to the edge between them, and the third is going to the child vertex.

My idea was that when I only have the parent, but they don't have a child, this query will only return one step, which is going to the first vertex, which is the parent, and then not going to any other step because no edge and child vertex exists. This way I could parse the result, and if there was only one step I could use that information to return with a message that the parent does exist, but does not have any children. If the parent wouldn't even exist, it would return with zero steps, because there wasn't even one vertex to begin with, and I could use that information as well.

But what really happens is that if the query can't totally complete, so there is no out edge (and supposedly no vertex at the end of it) it doesn't return with the steps that happened, it just returns the following:

{
   "_items": [],
   "attributes": {
      "x-ms-status-code": 200,
      "x-ms-request-charge": 8.24,
      "x-ms-total-request-charge": 8.24,
      "x-ms-server-time-ms": 7.7629,
      "x-ms-total-server-time-ms": 7.7629,
      "x-ms-activity-id": "26c2ca5f-8479-4bab-b4f4-7fe6969d5e51"
   },
   "length": 0
}

How could I modify the query to return with all steps, even though the whole query is incomplete? Does any alternative solution exist?


Solution

  • Using this sample data:

    g.addV('person').property('userId','x').as('x').
      addV('person').property('userId','y').as('y').
      addV('person').property('userId','z').as('z').
      addE('parentOf').from('x').to('y').iterate()
    

    You don't say what form you want your data as, so perhaps this would work for you:

    gremlin> g.V().has('person','userId', 'x').
    ......1>   project('parent','children').
    ......2>     by('userId').
    ......3>     by(out('parentOf').values('userId').fold())
    ==>[parent:x,children:[y]]
    gremlin> g.V().has('person','userId', 'y').
    ......1>   project('parent','children').
    ......2>     by('userId').
    ......3>     by(out('parentOf').values('userId').fold())
    ==>[parent:y,children:[]]