在Neo4j中,getProperty()变得越来越慢

时间:2014-09-30 14:37:31

标签: neo4j

我的目标是遍历节点的所有关系并打印出每个关系的一个特定属性。我的节点有很多关系(几十万)。我的迭代在迭代循环中变得越来越慢。有人可以对我的代码提出任何建议或意见吗?先谢谢你了!

    Node _node = sHelper.getNodeById(id);
    if (_node != null) {
        try (Transaction tx = graphDB.beginTx()) {
            if (_node.hasProperty("PublicKey")) {
                try {

                    double coin = 0;

                    BufferedWriter writer = new BufferedWriter(new FileWriter("./"+id+"_balance.txt"));

                    //Iterator<Relationship> rels = _node.getRelationships(Direction.INCOMING).iterator();
                    int kk = 0;
                    for(Relationship rel : _node.getRelationships(Direction.INCOMING)){
                        //Relationship rel = rels.next();

                        coin = (double) rel.getProperty("Bitcoin");

                        if((kk++)%10000==0){
                        System.out.println(appr+"\t"+coin);
                        }
                    }
                    kk=0;
                    //rels = _node.getRelationships(Direction.OUTGOING).iterator();
                    for(Relationship rel : _node.getRelationships(Direction.OUTGOING)){
                        //Relationship rel = rels.next();

                        coin = (double) rel.getProperty("Bitcoin");

                        if((kk++)%10000==0){
                        System.out.println(coin);
                        }
                    }

                    writer.flush();
                    writer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {


            }
            tx.success();
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        System.out.println("INVALID NODE ID!");
    }

1 个答案:

答案 0 :(得分:0)

如果您试图绘制每日余额,那么您不需要检索曾经存在的所有关系。我将在Cypher回答,因为我知道的就是:

某一天的交易总额:

MATCH (a:Address) WHERE ID(a) = 12345
MATCH (a)-[s:SENT]->()
WHERE s.timestamp >= tsStartOfDay AND s.timestamp <= tsEndOfDay
WITH a, SUM(s.coin) as sent
MATCH (a)<-[r:RECEIVE]-()
WHERE r.timestamp >= tsStartOfDay AND r.timestamp <= tsEndOfDay
RETURN SUM(r.coin) - sent

我已为您的发送/请求密钥以及AddressSENT的关系类型设置了标签RECEIVE。 tsStartOfDay和tsEndOfDay被假定为传递给查询的参数,这些参数表示您为其求和的那一天的长值时间戳。

您可以考虑在每个发送/接收发布时在节点上存储余额,以便不需要进行计算。因此,每次将新事务添加到系统时,它都会更新属性:

MATCH (a:Address) WHERE ID(a) = 12345
CREATE a<-[:RECEIVE{coin:0.01}]-(howeverYouModelFromNode)
SET a.balance = a.balance + 0.01

如果您已经在没有运行总计的情况下建模了大量数据,则可以运行查询,根据所有现有数据将其添加到每个地址节点。我假设您然后将所有这些值合并到钱包或帐户的总计中,然后您可以将每个地址节点的余额属性相加。

注意:小心将值存储在双精度变量中,可能会出现舍入错误,尤其是在处理比特币货币的分数性质时。