Gremlin迭代条件遍历

时间:2014-12-09 22:14:24

标签: graph-databases titan gremlin

我有一个具有以下结构的图表:

  1. 一些顶点表示真实世界的项目和某种类型,即“城市”的顶点和特定城市的顶点,如“伦敦”或“西雅图”。每个顶点的类型顶点可以有“is-a”边,即"London" -(is-a)-> "city""USA" -(is-a)-> "country"
  2. 顶点也可以通过“in”关系链接,即"London" -(in)-> "UK""Seattle" -(in)->"Washington"
  3. 某些顶点也可能具有“国内”关系,即"Seattle"->(in-country)->"USA",但有些可能没有。
  4. 可以有多个链接(即某个城市可以在两个国家之间存在争议,因此有两个“国内”或“在”链接) - 在这种情况下,应返回多个国家/地区。
  5. 任务是让每个顶点尝试找到它所在的国家(当然,它对于像“city”这样的通用顶点毫无意义,但在这种情况下它应该只生成null)。所以我试着做这样的事情:

    v.as('loopstep').ifThenElse{it.out('is-a').has('ID', 'country').hasNext()}{
     it
    }{
     it.ifThenElse{it.out('in-country').hasNext()}{
        it.out('in-country')
     }{
        it.out('in').loop('loopstep'){it.loops < 10 }
     }
    }
    

    但是在循环中产生NPE,例如:

    java.lang.NullPointerException
        at com.tinkerpop.pipes.branch.LoopPipe.getLoops(LoopPipe.java:75)
    

    等。看起来循环看不到“loopstep”标签。我做错了吗?编写此类遍历查询的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

我认为你不需要所有ifThenElse的东西。假设我现在你的模型正确,我认为你只需要这个:

gremlin> g = new TinkerGraph()                                                                     
==>tinkergraph[vertices:0 edges:0]
gremlin> g = new TinkerGraph()                                                                     
==>tinkergraph[vertices:0 edges:0]
gremlin> usa = g.addVertex([name:"USA"])
==>v[0]
gremlin> va = g.addVertex([name:"VA"])    
==>v[1]
gremlin> fairfax = g.addVertex([name:"Fairfax"])
==>v[2]
gremlin> country = g.addVertex([ID:"country"])
==>v[3]
gremlin> state = g.addVertex([ID:"state"])
==>v[4]
gremlin> city = g.addVertex([ID:"city"])
==>v[5]
gremlin> g.addEdge(null, fairfax, va, "in")
==>e[6][2-in->1]
gremlin> g.addEdge(null, fairfax, city, "is-a")
==>e[7][2-is-a->5]
gremlin> g.addEdge(null, va, usa, "in")    
==>e[8][1-in->0]
gremlin> g.addEdge(null, va, state, "is-a")
==>e[9][1-is-a->4]
gremlin> g.addEdge(null, fairfax, usa, "in-country")
==>e[10][2-in-country->0]
gremlin> g.addEdge(null, usa, country, "is-a")
==>e[11][0-is-a->3]
gremlin> fairfax.as('x').out('in','in-country').loop('x'){it.loops<10 && it.object.out('is-a').ID.next()!='country'}.dedup.name
==>USA

使用“in”或“in-country”标签从“city”(即fairfax)中走出最后一行。显然,如果我很幸运,我可以在“国内”遍历,我已经完成了。然后我循环回到x占位符,这样做的同时我仍然有少于10个循环,而我当前的顶点不是一个国家 - 否则我突然离开循环,因为我已达到我想要发出的国家顶点。我dedup因为您的架构允许多种方式到达“国内”和“内”的国家/地区。您可能需要一些错误处理或此处的内容,具体取决于您的数据集,但我认为这应该激发您提出最终解决方案。