我正在使用neo4j-java driver
在 Neo4j 中创建节点并借助以下密码查询。
String cipherQuery = "CREATE (n:MLObsTemp { personId: " + personId + ",conceptId: " + conceptId
+ ",obsId: " + obsId + ",MLObsId: " + mlObsId + ",encounterId: " + encounterId + "}) RETURN n";
创建查询的功能
createNeo4JObsNode(String cipherQuery);
功能的实现
private void createNeo4JObsNode(String cipherQuery) throws Exception {
try (ConNeo4j greeter = new ConNeo4j("bolt://localhost:7687", "neo4j", "qwas")) {
System.out.println("Executing query : " + cipherQuery);
try (Session session = driver.session()) {
StatementResult result = session.run(cipherQuery);
} catch (Exception e) {
System.out.println("Error" + e.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
使用以下代码与上述节点建立关系
String obsMatchQuery = "MATCH (m:MLObsTemp),(o:Obs) WHERE m.obsId=o.obsId CREATE (m)-[:OBS]->(o)";
createNeo4JObsNode(obsMatchQuery);
String personMatchQuery = "MATCH (m:MLObsTemp),(p:Person) WHERE m.personId=p.personId CREATE (m)-[:PERSON]->(p)";
createNeo4JObsNode(personMatchQuery);
String encounterMatchQuery = "MATCH (m:MLObsTemp),(e:Encounter) WHERE m.encounterId=e.encounterId CREATE (m)-[:ENCOUNTER]->(e)";
createNeo4JObsNode(encounterMatchQuery);
String conceptMatchQuery = "MATCH (m:MLObsTemp),(c:Concept) WHERE m.conceptId=c.conceptId CREATE (m)-[:CONCEPT]->(c)";
createNeo4JObsNode(conceptMatchQuery);
平均创建节点需要13秒,建立关系需要12秒。我的数据库中有350k记录,我必须创建节点及其各自的关系。
如何改进我的代码?而且,这是使用bolt服务器和neo4j-java驱动程序在Neo4j中创建节点的最佳方法吗?
我现在在我的代码中使用查询参数
HashMap<String, Object> parameters = new HashMap<String, Object>();
((HashMap<String, Object>) parameters).put("personId", 1390);
((HashMap<String, Object>) parameters).put("obsId", 14001);
((HashMap<String, Object>) parameters).put("conceptId", 5978);
((HashMap<String, Object>) parameters).put("encounterId", 10810);
((HashMap<String, Object>) parameters).put("mlobsId", 2);
String cypherQuery=
"CREATE (m:MLObsTemp { personId: $personId, ObsId: $obsId, conceptId: $conceptId, MLObsId: $mlobsId, encounterId: $encounterId}) "
+ "WITH m MATCH (p:Person { personId: $personId }) CREATE (m)-[:PERSON]->(p) "
+ "WITH m MATCH (e:Encounter {encounterId: $encounterId }) CREATE (m)-[:Encounter]->(e) "
+ "WITH m MATCH (o:Obs {obsId: $obsId }) CREATE (m)-[:OBS]->(o) "
+ "WITH m MATCH (c:Concept {conceptId: $conceptId }) CREATE (m)-[:CONCEPT]->(c) "
+ " RETURN m";
创建节点功能
try {
ConNeo4j greeter = new ConNeo4j("bolt://localhost:7687", "neo4j", "qwas");
try {
Session session = driver.session();
StatementResult result = session.run(cypherQuery, parameters);
System.out.println(result);
} catch (Exception e) {
System.out.println("[WARNING] Null Row");
}
} catch (Exception e) {
e.printStackTrace();
}
我也在执行索引以加快流程
CREATE CONSTRAINT ON (P:Person) ASSERT P.personId IS UNIQUE
CREATE CONSTRAINT ON (E:Encounter) ASSERT E.encounterId IS UNIQUE
CREATE CONSTRAINT ON (O:Obs) ASSERT O.obsId IS UNIQUE
CREATE CONSTRAINT ON (C:Concept) ASSERT C.conceptId IS UNIQUE
以下是1 cypher query-profile
的计划现在性能有所改善,但并不显着。我使用的是neo4j-java-driver 1.6.1版。如何批量我的密码查询以进一步提高性能。
答案 0 :(得分:2)
您应该尽量减少密码中的冗余工作。
MLObsTemp具有许多冗余属性,您正在搜索它以创建每个链接。关系无法为外键(节点ID)创建属性
我会推荐一个能完成所有事情的Cypher,并使用这样的参数......
CREATE (m:MLObsTemp)
WITH m MATCH (p:Person {id:"$person_id"}) CREATE (m)-[:PERSON]->(p)
WITH m MATCH (e:Encounter {id:"$encounter_id"}) CREATE (m)-[:Encounter]->(e)
WITH m MATCH (c:Concept {id:"$concept_id"}) CREATE (m)-[:CONCEPT]->(c)
// SNIP more MATCH/CREATE
RETURN m
这样,Neo4j不必为每个关系重复找到m。您不需要ID属性,因为这实际上就是您刚创建的关系。 Neo4j在行走边缘(关系)方面非常有效,所以如果你需要id值,请关注关系。
提示:( Neo4j版本的里程可能非常多)MATCH (n{id:"rawr"})
vs MATCH (n) WHERE n.id="rawr"
)$thing_id
语法。)此外,它还可以保护您免受Cypher注入(请参阅SQL injection)