如何让Neo4j Traversal更快?

时间:2014-05-22 00:06:26

标签: java neo4j bigdata

我正在为我的所有关系分配一个临时属性,但它需要花费大量时间来处理大约1,900个关系。我只想通过这样做获得更好的表现。

    TraversalDescription tempTraversal  = this.database.traversalDescription()
    .depthFirst()
    .uniqueness(Uniqueness.RELATIONSHIP_GLOBAL);
    String uuidString = "flw-"+uuid.toString();
    Transaction tx = database.beginTx();
    try {
        for(Relationship r : tempTraversal.traverse(this.nSource)
            .relationships()){
            if (r.hasProperty("weight"))
                r.setProperty(uuidString,r.getProperty("weight"));
        }
        tx.success();
    } catch (Exception e) {
        System.err.println("assingTempProperty: " + e);
        tx.failure();
    } finally {
        tx.close();
    }

还有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

好的,我调查了一下并学到了一些东西。

如果你有一个稀疏连接的图形,并且应用关系唯一性,你必须探索非常长的路径来真正找到图形中的所有独特关系,所以你必须来回蜿蜒,直到找到最后一个全局独特的关系。

您可以沿着一条路径探索整个图表。

为了将其编入数字,我生成了一个包含10%节点连接的400个节点的图表。

最终路径长度为:15845,探索1 288 374路径。

以下是我使用的代码:

@Test
public void testTraversal() throws Exception {
    GraphDatabaseService db = new TestGraphDatabaseFactory().newImpermanentDatabase();
    List<Node> nodes = new ArrayList<>();
    int count=0;
    long now = System.currentTimeMillis();
    try (Transaction tx = db.beginTx()) {
        for (int i=0;i<400;i++) {
            nodes.add(db.createNode());
        }
        DynamicRelationshipType knows = DynamicRelationshipType.withName("KNOWS");
        for (Node node1 : nodes) {
            for (Node node2 : nodes) {
                double random = Math.random();
                if (random < 0.1 && node1 != node2) {
                    node1.createRelationshipTo(node2, knows).setProperty("weight",random);
                    count++;
                }
            }
        }
        tx.success();
    }
    System.out.println("generated rel-count = " + count+" time "+(System.currentTimeMillis()-now)+" ms");

    now = System.currentTimeMillis();
    String uuidString = "flw-"+ now;
    count=0;
    try (Transaction tx = db.beginTx()) {
        for (Relationship r : GlobalGraphOperations.at(db).getAllRelationships()) {
            if (r.hasProperty("weight"))
                r.setProperty(uuidString, r.getProperty("weight"));
            count++;
        }
        tx.success();
    }
    System.out.println("global graph ops rel-count = " + count+" time "+(System.currentTimeMillis()-now)+" ms");

    final AtomicInteger pathLenght=new AtomicInteger();
    final AtomicInteger pathCount=new AtomicInteger();
    TraversalDescription tempTraversal  = db.traversalDescription()
            .depthFirst()
            .uniqueness(new UniquenessFactory() {
                            @Override
                            public UniquenessFilter create(Object optionalParameter) {
                                return new UniquenessFilter() {
                                    Set<Relationship> rels = new HashSet<Relationship>(100000);
                                    @Override
                                    public boolean checkFirst(TraversalBranch branch) {
                                        pathCount.incrementAndGet();
                                        pathLenght.set(Math.max(pathLenght.get(),branch.length()));
                                        return rels.add(branch.lastRelationship());
                                    }

                                    @Override
                                    public boolean check(TraversalBranch branch) {
                                        pathCount.incrementAndGet();
                                        pathLenght.set(Math.max(pathLenght.get(),branch.length()));
                                        return rels.add(branch.lastRelationship());
                                    }
                                };
                            }
                        }
     );
    now = System.currentTimeMillis();
    Transaction tx = db.beginTx();
    count=0;
    try {
        for(Relationship r : tempTraversal.traverse(nodes.get(0))
                .relationships()){
            if (r.hasProperty("weight"))
                r.setProperty(uuidString,r.getProperty("weight"));
            count++;
        }
        tx.success();
    } catch (Exception e) {
        System.err.println("assingTempProperty: " + e);
        tx.failure();
    } finally {
        tx.close();
    }
    System.out.println("rel-count = " + count+" time "+(System.currentTimeMillis()-now)+" ms pathlength "+pathLenght.get()+" pathCount "+pathCount.get());
}