1

In Azure Cosmos Graph DB I have the following Graph DB. enter image description here I am attempting to create a query that returns the following output:

Ideal Output

[
    "Person 1":{
        skills:[{"MS OFFICE":"PASS"}],
        orgPath:"Random Inc/"
    },
    "Person 2":{
        skills:[{".NET":"PASS"},{"Accounting":"FAIL"},{"Python":"PASS"}],
        orgPath:"Random Inc/Person 1/"
    },
    "Person 3":{
        skills:[{"MS OFFICE":"PASS"}],
        orgPath:"Random Inc/Person 1/"
    },
    "Person 4":{
        skills:[{"MS OFFICE":"FAIL"},{"Python":"PASS"}],
        orgPath:"Random Inc/Person 1/Person 3/"
    }

]

However I am getting stuck after the initial .group().by() in gremlin.

Query thus Far:

g.V().hasLabel('Person').group().by('name').by(outE('scored').inV().fold())

My current Query does return a list of JSON Objects whose key is the Name of the person Node and inside each JSON Object is the Full JSON Representation of each Skill Node assigned to that particular Person Node.

Questions:

  1. Is there a way select of the Skill Node to return the pattern of skillName:skillValue?
  2. Is there a way to also print the path the traversal took following the edge of "isManagerOf"
Ad Astra
  • 75
  • 1
  • 7
  • For Question 2, I think I might have found a pattern of query to use/modify `g.V().repeat(out()).emit().tree()`. – Ad Astra Sep 28 '18 at 16:53

1 Answers1

4

First off, you can save people a lot of time if you post a tiny script to create your sample graph, instead of a picture. Something like this:

g.addV("Person").property("Name","Person 1").as("p1").
  addV("Person").property("Name","Person 2").as("p2").
  addV("Person").property("Name","Person 3").as("p3").
  addV("Person").property("Name","Person 4").as("p4").
  addV("Skill").property("skillName","MS OFFICE").
                property("skillVAL","PASS").as("msoP").
  addV("Skill").property("skillName","MS OFFICE").
                property("skillVAL","FAIL").as("msoF").
  addV("Skill").property("skillName",".NET").
                property("skillVAL","PASS").as("net").
  addV("Skill").property("skillName","Accounting").
                property("skillVAL","FAIL").as("acc").
  addV("Skill").property("skillName","Python").
                property("skillVAL","PASS").as("py").
  addV("Business").property("Name","Random INC").as("rnd").
  addE("scored").from("p1").to("msoP").
  addE("scored").from("p2").to("net").
  addE("scored").from("p2").to("acc").
  addE("scored").from("p2").to("py").
  addE("scored").from("p3").to("msoP").
  addE("scored").from("p4").to("py").
  addE("scored").from("p4").to("msoF").
  addE("isManagerOf").from("p1").to("p2").
  addE("isManagerOf").from("p1").to("p3").
  addE("isManagerOf").from("p3").to("p4").
  addE("employs").from("rnd").to("p1").
  addE("employs").from("rnd").to("p2").
  addE("employs").from("rnd").to("p3").
  addE("employs").from("rnd").to("p4").iterate()

Now, to get the result in (almost) the exact format you described, your query would look like this:

g.V().hasLabel("Person").as("p").
  project("name","skills","orgPath").
    by("Name").
    by(out("scored").
       group().
         by("skillName").
         by(values("skillVAL"))).
    by(__.as("v").
       until(select("v").hasLabel("Business")).
         repeat(select("v").
                coalesce(__.in("isManagerOf"),
                         __.in("employs")).
                project("i","v").
                  by(loops()).
                  by().as("iv")).
         select(all, "iv").unfold().
         order().
           by(select("i"), decr).
         select("v").values("Name").
         fold()).
  group().
    by(select("name")).
    by(select("skills","orgPath")).unfold()

All the group()ing is unnecessary in my opinion and is really just there to bring the result in the expected format. The only thing that doesn't match your expectation is the orgPath - it's a list of Strings rather than a single delimited String; that's because TinkerPop doesn't support any String operations (yet).

Anyway, let me emphasize again that the query is only as complex as it is because you wanted to get the result in a very specific format. Without this requirement, the query would only consist of a few projections.

That said, the result of the query above looks like this:

==>Person 1={skills={MS OFFICE=PASS}, orgPath=[Random INC]}
==>Person 2={skills={Accounting=FAIL, .NET=PASS, Python=PASS}, orgPath=[Random INC, Person 1]}
==>Person 3={skills={MS OFFICE=PASS}, orgPath=[Random INC, Person 1]}
==>Person 4={skills={MS OFFICE=FAIL, Python=PASS}, orgPath=[Random INC, Person 1, Person 3]}
Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
  • Thanks for the suggestions and the queries. Let me test it out on Azure to make sure that Azure has implemented these functions, it doesn't trigger Azure to exceed it's RU's too often, and I can wrap my head around how the query works. – Ad Astra Sep 28 '18 at 18:09