Java 使用GremlinPipeline查找最短路径

Java 使用GremlinPipeline查找最短路径,java,gremlin,titan,Java,Gremlin,Titan,我的数据存储在Titan graph数据库中。我试图找到两个顶点(v1和v2)之间的最短路径。目前我有以下代码: final Vertex v1 = titanGraph.getVertices("nodeId", "110969224").iterator().next(); final Vertex v2 = titanGraph.getVertices("nodeId", "141396276").iterator().next(); System.out.prin

我的数据存储在Titan graph数据库中。我试图找到两个顶点(v1和v2)之间的最短路径。目前我有以下代码:

    final Vertex v1 = titanGraph.getVertices("nodeId", "110969224").iterator().next();
    final Vertex v2 = titanGraph.getVertices("nodeId", "141396276").iterator().next();
    System.out.println(v2);

    final GremlinPipeline<String, List> pipe = new GremlinPipeline<String, List>(v1)
            .as("similar")
            .both("similar")
            .loop("similar", new PipeFunction<LoopBundle<Vertex>, Boolean>() {
                @Override
                public Boolean compute(LoopBundle<Vertex> bundle) {
                    return bundle.getLoops() < 4 && bundle.getObject() != v2;
                }
            })  
            .path();
    List results = new ArrayList();
    Bindings bindings = engine.createBindings();
    bindings.put("v1", v1); 
    bindings.put("v2", v2); 
    bindings.put("results", results);

    engine.eval("v1.both.filter{it.nodeId!='nodeId'}.loop('similar'){!it.object.equals(v2) && it.loop < 5}.paths.fill(results)", bindings);

任何关于这些问题的建议都是很好的。

您的代码看起来有点类似于GremlinDocs中的最短路径配方:

在评估顶点的两个方向时,您可能需要阅读该部分的全部内容,这两个方向都会产生影响,并且使用store/except模式可以更好地处理

一旦你有了所有的路径,你只需要从返回的列表中选择最短的一条。在纯Java中,这比使用Groovy要多一些,但它基本上可以归结为对路径长度进行排序,然后选择最短的路径。在groovy中,这类似于:

gremlin> g.v(1).out.loop(1){it.object.id != "3" && it.loops < 6}.path.sort{a,b->a.size()<=>b.size()}   
==>[v[1], v[3]]
==>[v[1], v[4], v[3]]
gremlin>g.v(1).out.loop(1){it.object.id!=“3”&&it.loops<6}.path.sort{a,b->a.size()b.size()}
==>[v[1],v[3]]
==>[v[1],v[4],v[3]]
看到这一点,我想知道您是否可以随时弹出管道中的第一个项目,因为这将是检测到的最早路径,因此也是最短的路径:

gremlin> g.v(1).out.loop(1){it.object.id != "3" && it.loops < 6}.path[0]                            
==>[v[1], v[3]]
gremlin>g.v(1).out.loop(1){it.object.id!=“3”&&it.loops<6}.path[0]
==>[v[1],v[3]]

您可能想尝试一下,但这听起来像是一个很有前途的理论,如果您只需要检测到第一条最短路径,它将允许您短路管道

你认为如果我使用这个,性能会最差,我可以使用groovy?我在所有生产项目上都只使用gremlin groovy。除了使用反射来获取属性名等可以避免的情况外,它以最小的开销执行得很好。我总是建议从gremlin groovy开始,如果您发现您绝对需要优化,那么在非主流情况下可以切换到java。拥有一个基于maven的项目将使java/groovy的混合变得完全无缝。我建议试试。好的,我会试试这个解决方案,如果有问题我会回来。感谢您不确定这是否是唯一的问题,但您正在循环到“相似”,但它似乎没有在
步骤中定义为
。请注意,我关于使用Groovy的建议更适用于在项目中包含Groovy类文件。对我来说,集成Maven项目是一种常见的模式,而不是嵌入式脚本引擎。这就是说,嵌入式脚本引擎正是Rexster的工作方式,因此您所做的肯定是可能的。问题是,您有很多代码(Gremlin)作为字符串嵌入,而这些代码不像项目中实际的Groovy类文件那样可维护。
gremlin> g.v(1).out.loop(1){it.object.id != "3" && it.loops < 6}.path[0]                            
==>[v[1], v[3]]