如何通过传递参数删除带有属性的关系?

huangapple go评论79阅读模式
英文:

How to delete relationships with properties by passing parameters?

问题

以下是您要翻译的部分:

环境:

  1. Neo4j-4.4.x
  2. 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

图-1:
如何通过传递参数删除带有属性的关系?

为什么我的下面使用参数映射的方法不起作用?

@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: &#39;teacher_001&#39;})  MATCH (object:Student{student_id:&#39;student_001&#39;})  MATCH (subject)-[relation:educate]->(object)  WHERE relation = $relation_prop DELETE relation

然而,上述的Cypher查询可以在Neo4j浏览器中成功执行(见图-2)。我做错了什么?感谢任何有帮助的回复。

图-2:
如何通过传递参数删除带有属性的关系?

我尝试了几种设置参数的方法,但都没有成功。

String conditionDeleteCypher = " WHERE relation = $relation_prop";
String conditionDeleteCypher = " WHERE relation =+ $relation_prop";
String conditionDeleteCypher = " WHERE relation += $relation_prop";

我提供的@Test代码是完全可执行的,没有错误消息。执行后,Neo4j浏览器仍然可以找到目标关系,这表明该方法已执行但没有生效。

英文:

env:

  1. Neo4j-4.4.x
  2. 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: &#39;teacher_001&#39;})  
merge (object:Student{student_id:&#39;student_001&#39;})  
merge (subject)-[relation:educate]-&gt;(object) set relation.year=&#39;3&#39;  return subject,relation,object

figure-1:
如何通过传递参数删除带有属性的关系?

Why does my following approach with the help of parameters maps not work?

@Test
public void testDeleteEdgeWithProperties_001() {
    Driver driver = GraphDatabase.driver(&quot;neo4j://localhost:7687&quot;, AuthTokens.basic(&quot;neo4j&quot;, &quot;neo4j123&quot;));
    Session session = driver.session();
    Transaction transaction = session.beginTransaction();

    String relationModelType = &quot;educate&quot;;
    String subjectModelType = &quot;Teacher&quot;;
    String subjectKey = &quot;teacher_id&quot;;
    String subjectId = &quot;teacher_001&quot;;
    String objectModelType = &quot;Student&quot;;
    String objectKey =&quot;student_id&quot;;
    String objectId = &quot;student_001&quot;;

    Map&lt;String, Object&gt; properties = new HashMap&lt;&gt;();
    properties.put(&quot;year&quot;,&quot;3&quot;);
    Map&lt;String, Object&gt; params = new HashMap&lt;&gt;();
    params.put(&quot;relation_prop&quot;, properties == null ? new HashMap&lt;&gt;() : properties);

    // 删除
    String conditionDeleteCypher = &quot; WHERE relation = $relation_prop&quot;;
    String cypher =  &quot; MATCH (subject:&quot; + subjectModelType + &quot;{&quot; + subjectKey + &quot;: &#39;&quot; + subjectId + &quot;&#39;}) &quot; +
            &quot; MATCH (object:&quot; + objectModelType + &quot;{&quot; + objectKey + &quot;:&#39;&quot; + objectId + &quot;&#39;}) &quot; +
            &quot; MATCH (subject)-[relation:&quot; + relationModelType +&quot;]-&gt;(object) &quot; +
            conditionDeleteCypher +
            &quot; DELETE relation&quot;;

    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: &#39;teacher_001&#39;})  MATCH (object:Student{student_id:&#39;student_001&#39;})  MATCH (subject)-[relation:educate]-&gt;(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

figure-2:
如何通过传递参数删除带有属性的关系?

I tried several ways to set the parameter, but none of them worked.

String conditionDeleteCypher = &quot; WHERE relation = $relation_prop&quot;;
String conditionDeleteCypher = &quot; WHERE relation =+ $relation_prop&quot;;
String conditionDeleteCypher = &quot; WHERE relation += $relation_prop&quot;;

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&lt;String,Object&gt; params = new HashMap&lt;&gt;();
params.put( &quot;name&quot;, &quot;Johan&quot; );

String query =
&quot;MATCH (n:Person)&quot; + &quot;\n&quot; +
&quot;WHERE n.name = $name&quot; + &quot;\n&quot; +
&quot;RETURN n&quot;;

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"
  }
}

这不会起作用,因为有两个原因:

  1. relation_prop 不是有效的 relation 属性。
  2. 有很多其他内部属性,是关系的一部分。

在你在 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: &#39;teacher_001&#39;})  
MATCH (object:Student{student_id:&#39;student_001&#39;})  
MATCH (subject)-[relation:educate]-&gt;(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: &quot;3&quot;
  }
}

This won't work because of two reasons:

  1. relation_prop is not a valid relation property.
  2. 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(&quot;neo4j://localhost:7687&quot;, AuthTokens.basic(&quot;neo4j&quot;, &quot;neo4j123&quot;));
    Session session = driver.session();
    Transaction transaction = session.beginTransaction();

    String relationModelType = &quot;educate&quot;;
    String subjectModelType = &quot;Teacher&quot;;
    String subjectKey = &quot;teacher_id&quot;;
    String subjectId = &quot;teacher_001&quot;;
    String objectModelType = &quot;Student&quot;;
    String objectKey =&quot;student_id&quot;;
    String objectId = &quot;student_001&quot;;

    Map&lt;String, Object&gt; properties = new HashMap&lt;&gt;();
    properties.put(&quot;year&quot;,&quot;3&quot;);

    // 删除
    String conditionDeleteCypher = &quot; WHERE relation.year = $year&quot;;
    String cypher =  &quot; MATCH (subject:&quot; + subjectModelType + &quot;{&quot; + subjectKey + &quot;: &#39;&quot; + subjectId + &quot;&#39;}) &quot; +
            &quot; MATCH (object:&quot; + objectModelType + &quot;{&quot; + objectKey + &quot;:&#39;&quot; + objectId + &quot;&#39;}) &quot; +
            &quot; MATCH (subject)-[relation:&quot; + relationModelType +&quot;]-&gt;(object) &quot; +
            conditionDeleteCypher +
            &quot; DELETE relation&quot;;

    System.out.println(cypher);
    transaction.run(cypher, properties);
    transaction.commit();
    transaction.close();
}

huangapple
  • 本文由 发表于 2023年5月28日 16:40:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350626.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定