分组依据和迭代路径的Gremlin应用

时间:2018-09-28 14:51:13

标签: azure-cosmosdb gremlin

在Azure Cosmos图形数据库中,我具有以下图形数据库。 enter image description here我正在尝试创建一个查询,该查询返回以下输出:

理想的输出

[
    "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/"
    }

]

但是在gremlin中最初的.group()。by()之后,我陷入了困境。

到目前为止查询:

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

我当前的查询确实返回一个JSON对象列表,其键为人员节点的名称,并且在每个JSON对象内部是分配给该特定人员节点的每个技能节点的完整JSON表示形式。

问题:

  1. 是否可以选择技能节点以返回skillName:skillValue的模式?
  2. 是否有一种方法也可以打印遍历“ isManagerOf”的边缘的遍历路径

1 个答案:

答案 0 :(得分:1)

首先,如果发布一个小的脚本来创建示例图而不是图片,则可以节省很多时间。像这样:

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()

现在,要以(几乎)您所描述的确切格式获得结果,您的查询将如下所示:

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()

在我看来,所有group()处理都是不必要的,实际上只是为了使结果以预期的格式存在。唯一与您的期望不符的是orgPath-它是字符串列表,而不是单个定界字符串;那是因为TinkerPop还不支持任何String操作。

无论如何,让我再次强调一下,查询只是因为它是如此复杂,因为您希望以非常特定的格式获得结果。没有此要求,查询将仅包含一些预测。

也就是说,上面的查询结果如下:

==>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]}