我的目标是遍历节点的所有关系并打印出每个关系的一个特定属性。我的节点有很多关系(几十万)。我的迭代在迭代循环中变得越来越慢。有人可以对我的代码提出任何建议或意见吗?先谢谢你了!
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!");
}
答案 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
我已为您的发送/请求密钥以及Address
和SENT
的关系类型设置了标签RECEIVE
。 tsStartOfDay和tsEndOfDay被假定为传递给查询的参数,这些参数表示您为其求和的那一天的长值时间戳。
您可以考虑在每个发送/接收发布时在节点上存储余额,以便不需要进行计算。因此,每次将新事务添加到系统时,它都会更新属性:
MATCH (a:Address) WHERE ID(a) = 12345
CREATE a<-[:RECEIVE{coin:0.01}]-(howeverYouModelFromNode)
SET a.balance = a.balance + 0.01
如果您已经在没有运行总计的情况下建模了大量数据,则可以运行查询,根据所有现有数据将其添加到每个地址节点。我假设您然后将所有这些值合并到钱包或帐户的总计中,然后您可以将每个地址节点的余额属性相加。
注意:小心将值存储在双精度变量中,可能会出现舍入错误,尤其是在处理比特币货币的分数性质时。