4

I have the following Gremlin queries that ran successfully in CosmosDB:

g.addV('person').property(id, 'grand_father').property('name', 'Grand Father')
g.addV('person').property(id, 'father').property('name', 'Father')
g.addV('person').property(id, 'child').property('name', 'Child')
g.V('grand_father').addE('father_of').to(V('father'))
g.V('father').addE('father_of').to(V('child'))

I ran the query g.V('grand_father').repeat(out()).emit().tree() which generates the following output:

[
  {
    "grand_father": {
      "key": {
        "id": "grand_father",
        "label": "person",
        "type": "vertex",
        "properties": {
          "name": [
            {
              "id": "2b687c65-6490-4846-a5ef-1b7d67e51916",
              "value": "Grand Father"
            }
          ]
        }
      },
      "value": {
        "father": {
          "key": {
            "id": "father",
            "label": "person",
            "type": "vertex",
            "properties": {
              "name": [
                {
                  "id": "c1f75463-8aa5-4c15-854d-88be0ec9cdc9",
                  "value": "Father"
                }
              ]
            }
          },
          "value": {
            "child": {
              "key": {
                "id": "child",
                "label": "person",
                "type": "vertex",
                "properties": {
                  "name": [
                    {
                      "id": "d74d6286-5fa9-4b90-9619-1f173d5da53e",
                      "value": "Child"
                    }
                  ]
                }
              },
              "value": {}
            }
          }
        }
      }
    }
  }
]

I want to transform the above GraphSON tree again to generate a custom hierarchical tree of the following format.

{
   "person":{
      "name":"Grand Father"
   },
   "children":[
      {
         "person":{
            "name":"Father"
         },
         "children":[
            {
               "person":{
                  "name":"Child"
               }
            }
         ]
      }
   ]
}

What changes that I need to make to g.V('grand_father').repeat(out()).emit().tree() to achieve the result?

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
wonderful world
  • 10,969
  • 20
  • 97
  • 194
  • Hi, any chance you managed to achieve that? I am looking to do the same and I ended up adding a post script with tons of regexp to do it... – Alexandre Mélard Jun 13 '21 at 18:07

1 Answers1

2

I think that the following gets pretty close to what you're asking:

gremlin> g.V('grand_father').
......1>   repeat(out()).
......2>     emit().
......3>   tree().
......4>     by(group().
......5>          by(label).
......6>          by(valueMap('name').by(unfold())).
......7>        unfold().unfold())
==>[person={name=Grand Father}:[person={name=Father}:[person={name=Child}:[]]]]

Note that tree() takes a by() modulator which applies the anonymous traversal given to it as an argument to each item of the tree. I didn't capture the "children" leaf in your JSON output, but perhaps this gets you close enough to your target without introducing more complexity. Note that CosmosDB might not yet support the valueMap('name').by(unfold()) trick in which case you can remove the by(unfold()) and be left with List wrapping the value, replace it with project('name').by('name'), or replace it with the "old" way of unfolding a valueMap() shown next:

gremlin> g.V('grand_father').
......1>   repeat(out()).
......2>     emit().
......3>   tree().
......4>     by(group().
......5>          by(label).
......6>          by(valueMap('name').
......7>             unfold().
......8>             group().
......9>               by(select(keys)).
.....10>               by(select(values).unfold())).
.....11>        unfold().unfold())
==>[person={name=Grand Father}:[person={name=Father}:[person={name=Child}:[]]]]
stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • For the second query, I get the error message: ```ExceptionType : GraphAssertException\nExceptionMessage :\r\n\tcompositeObjField != null``` – wonderful world Jun 27 '19 at 19:40
  • For the first query, I get the error message: ```Unsupported Error: Gremlin op does not support by(traversal)\n``` – wonderful world Jun 27 '19 at 19:42
  • 1
    sorry....my examples run against the reference graph implementation for TinkerPop which is meant to be the standard for demonstrating expected Gremlin semantics, so theoretically, every TinkerPop-enabled graph should have the same behavior as it. unfortunately, every so often CosmosDB doesn't quite match the expected semantics. i expected the first query to fail as that syntax i mentioned is new to 3.4.x and I figured that CosmosDB didn't support that yet. i'm less sure about why the second query is failing just this moment. – stephen mallette Jun 27 '19 at 19:58
  • I solved this problem with SQL and LINQ before by selecting all the nodes, and iterating through them in a ```for``` loop to generate the tree. I tried to solve this problem an year ago with ```neo4j``` but could not because they did not have a ```tree()``` function out of the box. I'm leaning towards a solution of generate a tree with ```g.V('grand_father').repeat(out()).emit().tree()```, string parse it and generate the custom tree that I need. That is double processing (1) at the Gremlin server to generate the firs tree (2) at the API level again to generate the custom tree. – wonderful world Jun 28 '19 at 00:40
  • Do you recommend a book or blog that describe how a function like ```tree()``` or Gremling **step** works? – wonderful world Jun 28 '19 at 00:44
  • 1
    that may be your're only approach. i'd only recommend that you use `by()` as i did to pair down your results a bit to just the data you need to save on serialization costs and network payload size. there really is no other documentation for `tree()` besides there Reference Documentation http://tinkerpop.apache.org/docs/current/reference/#tree-step and the Practical Gremlin book: http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html There really isn't much to it beyond what I've demonstrated with it. Pretty simple step. – stephen mallette Jun 28 '19 at 09:57