英文:
How to delete relationships with properties by passing parameters?
问题
以下是您要翻译的部分:
环境:
- Neo4j-4.4.x
- neo4j-jdbc-driver 4.0.9
假设我执行以下的Cypher查询来获取一个“teacher”节点和一个“student”节点,它们之间的关系是“educate”,并且这个关系有一个年份属性。
Cypher查询:
merge (subject:Teacher{teacher_id: 'teacher_001'})
merge (object:Student{student_id:'student_001'})
merge (subject)-[relation:educate]->(object) set relation.year='3' return subject,relation,object
为什么我的下面使用参数映射的方法不起作用?
@Test
public void testDeleteEdgeWithProperties_001() {
Driver driver = GraphDatabase.driver("neo4j://localhost:7687", AuthTokens.basic("neo4j", "neo4j123"));
Session session = driver.session();
Transaction transaction = session.beginTransaction();
String relationModelType = "educate";
String subjectModelType = "Teacher";
String subjectKey = "teacher_id";
String subjectId = "teacher_001";
String objectModelType = "Student";
String objectKey ="student_id";
String objectId = "student_001";
Map<String, Object> properties = new HashMap<>();
properties.put("year","3");
Map<String, Object> params = new HashMap<>();
params.put("relation_prop", properties == null ? new HashMap<>() : properties);
// 删除
String conditionDeleteCypher = " WHERE relation = $relation_prop";
String cypher = " MATCH (subject:" + subjectModelType + "{" + subjectKey + ": '" + subjectId + "'}) " +
" MATCH (object:" + objectModelType + "{" + objectKey + ":'" + objectId + "'}) " +
" MATCH (subject)-[relation:" + relationModelType + "]->(object) " +
conditionDeleteCypher +
" DELETE relation";
System.out.println(cypher);
transaction.run(cypher, params);
transaction.commit();
transaction.close();
}
上述方法打印的Cypher查询如下:
MATCH (subject:Teacher{teacher_id: 'teacher_001'}) MATCH (object:Student{student_id:'student_001'}) MATCH (subject)-[relation:educate]->(object) WHERE relation = $relation_prop DELETE relation
然而,上述的Cypher查询可以在Neo4j浏览器中成功执行(见图-2)。我做错了什么?感谢任何有帮助的回复。
我尝试了几种设置参数的方法,但都没有成功。
String conditionDeleteCypher = " WHERE relation = $relation_prop";
String conditionDeleteCypher = " WHERE relation =+ $relation_prop";
String conditionDeleteCypher = " WHERE relation += $relation_prop";
我提供的@Test代码是完全可执行的,没有错误消息。执行后,Neo4j浏览器仍然可以找到目标关系,这表明该方法已执行但没有生效。
英文:
env:
- Neo4j-4.4.x
- neo4j-jdbc-driver 4.0.9
Image that I execute the following cypher to get a ‘teacher’ node and a ‘student’ node, the relationship between them is ‘educate’, and the relationship has a year attribute.
cypher:
merge (subject:Teacher{teacher_id: 'teacher_001'})
merge (object:Student{student_id:'student_001'})
merge (subject)-[relation:educate]->(object) set relation.year='3' return subject,relation,object
Why does my following approach with the help of parameters maps not work?
@Test
public void testDeleteEdgeWithProperties_001() {
Driver driver = GraphDatabase.driver("neo4j://localhost:7687", AuthTokens.basic("neo4j", "neo4j123"));
Session session = driver.session();
Transaction transaction = session.beginTransaction();
String relationModelType = "educate";
String subjectModelType = "Teacher";
String subjectKey = "teacher_id";
String subjectId = "teacher_001";
String objectModelType = "Student";
String objectKey ="student_id";
String objectId = "student_001";
Map<String, Object> properties = new HashMap<>();
properties.put("year","3");
Map<String, Object> params = new HashMap<>();
params.put("relation_prop", properties == null ? new HashMap<>() : properties);
// 删除
String conditionDeleteCypher = " WHERE relation = $relation_prop";
String cypher = " MATCH (subject:" + subjectModelType + "{" + subjectKey + ": '" + subjectId + "'}) " +
" MATCH (object:" + objectModelType + "{" + objectKey + ":'" + objectId + "'}) " +
" MATCH (subject)-[relation:" + relationModelType +"]->(object) " +
conditionDeleteCypher +
" DELETE relation";
System.out.println(cypher);
transaction.run(cypher, params);
transaction.commit();
transaction.close();
}
The cypher printed by the above method is as follows:
MATCH (subject:Teacher{teacher_id: 'teacher_001'}) MATCH (object:Student{student_id:'student_001'}) MATCH (subject)-[relation:educate]->(object) WHERE relation = $relation_prop DELETE relation
However, the above cypher can be executed successfully in the neo4j browser (see figure-2 below). What's wrong with me? Appreciate any helpful responses
I tried several ways to set the parameter, but none of them worked.
String conditionDeleteCypher = " WHERE relation = $relation_prop";
String conditionDeleteCypher = " WHERE relation =+ $relation_prop";
String conditionDeleteCypher = " WHERE relation += $relation_prop";
The @Test code I provided is completely executable, no error message.
After execution, the neo4j browser can still find the target relationship, indicating that the method was executed but did not take effect.
答案1
得分: 0
你可以查看官方的 Neo4J Java 文档,其中包含许多示例。
特别是这些示例:
Map<String, Object> params = new HashMap<>();
params.put("name", "Johan");
String query =
"MATCH (n:Person)" + "\n" +
"WHERE n.name = $name" + "\n" +
"RETURN n";
Result result = transaction.execute(query, params);
并且可以使您的最小用例更轻便,去掉任何无用的代码。
英文:
You can check the official Neo4J java documentation with many examples.
Especially these one :
Map<String,Object> params = new HashMap<>();
params.put( "name", "Johan" );
String query =
"MATCH (n:Person)" + "\n" +
"WHERE n.name = $name" + "\n" +
"RETURN n";
Result result = transaction.execute( query, params );
And make your minimum use case lighter removing any useless code.
答案2
得分: 0
你的代码生成的查询在逻辑上是不正确的:
MATCH (subject:Teacher{teacher_id: 'teacher_001'})
MATCH (object:Student{student_id:'student_001'})
MATCH (subject)-[relation:educate]->(object) WHERE relation = $relation_prop
DELETE relation
在这个查询中,你正在将整个 Neo4j Relationship
对象与一个查询对象进行比较,查询对象如下:
{
relation_prop: {
year: "3"
}
}
这不会起作用,因为有两个原因:
relation_prop
不是有效的relation
属性。- 有很多其他内部属性,是关系的一部分。
在你在 Neo4j Browser
上运行的查询中,你只检查了 year
属性的值。为了修复它,你可以尝试以下代码:
@Test
public void testDeleteEdgeWithProperties_001() {
Driver driver = GraphDatabase.driver("neo4j://localhost:7687", AuthTokens.basic("neo4j", "neo4j123"));
Session session = driver.session();
Transaction transaction = session.beginTransaction();
String relationModelType = "educate";
String subjectModelType = "Teacher";
String subjectKey = "teacher_id";
String subjectId = "teacher_001";
String objectModelType = "Student";
String objectKey = "student_id";
String objectId = "student_001";
Map<String, Object> properties = new HashMap<>();
properties.put("year", "3");
// 删除
String conditionDeleteCypher = " WHERE relation.year = $year";
String cypher = " MATCH (subject:" + subjectModelType + "{" + subjectKey + ": '" + subjectId + "'}) " +
" MATCH (object:" + objectModelType + "{" + objectKey + ":'" + objectId + "'}) " +
" MATCH (subject)-[relation:" + relationModelType + "]->(object) " +
conditionDeleteCypher +
" DELETE relation";
System.out.println(cypher);
transaction.run(cypher, properties);
transaction.commit();
transaction.close();
}
英文:
The query generated by your code, is logically incorrect:
MATCH (subject:Teacher{teacher_id: 'teacher_001'})
MATCH (object:Student{student_id:'student_001'})
MATCH (subject)-[relation:educate]->(object) WHERE relation = $relation_prop
DELETE relation
In this query, you are comparing the whole Neo4j Relationship
object, to a query object, which is like this:
{
relation_prop: {
year: "3"
}
}
This won't work because of two reasons:
relation_prop
is not a validrelation
property.- There are a lot of other internal properties, part of a relationship.
In the query you ran on Neo4j Browser
, you are only checking the value of the year
property. To fix it you can try this:
@Test
public void testDeleteEdgeWithProperties_001() {
Driver driver = GraphDatabase.driver("neo4j://localhost:7687", AuthTokens.basic("neo4j", "neo4j123"));
Session session = driver.session();
Transaction transaction = session.beginTransaction();
String relationModelType = "educate";
String subjectModelType = "Teacher";
String subjectKey = "teacher_id";
String subjectId = "teacher_001";
String objectModelType = "Student";
String objectKey ="student_id";
String objectId = "student_001";
Map<String, Object> properties = new HashMap<>();
properties.put("year","3");
// 删除
String conditionDeleteCypher = " WHERE relation.year = $year";
String cypher = " MATCH (subject:" + subjectModelType + "{" + subjectKey + ": '" + subjectId + "'}) " +
" MATCH (object:" + objectModelType + "{" + objectKey + ":'" + objectId + "'}) " +
" MATCH (subject)-[relation:" + relationModelType +"]->(object) " +
conditionDeleteCypher +
" DELETE relation";
System.out.println(cypher);
transaction.run(cypher, properties);
transaction.commit();
transaction.close();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论