假設我想建立下圖 User nodes 間 IS_FRIEND_OF 與 WORKS_WITH 的關係
透過 Spring Data 建立以下的 repository class (分別傳入三個參數,包含來源 node、目的 node以及要建立的關係)
package neo4j.springdata.repository; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import neo4j.springdata.vo.User; @Repository public interface UserRepository extends CrudRepository<User, Long> { @Query(" match (from:User), (to:User) " + " where from.name={from} and to.name={to} " + " merge (from)-[:{relation}]->(to) ") void createRelation(@Param("from") String from, @Param("to") String to, @Param("relation") String relation); }
但在執行時,出現以下 runtime exception
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Invalid input '{': expected whitespace or a rel type name (line 1, column 87 (offset: 86)) "match (from:User), (to:User) where from.name={from} and to.name={to} merge (from)-[:{relation}]->(to)" ^ at org.neo4j.driver.internal.net.SocketResponseHandler.handleFailureMessage(SocketResponseHandler.java:76) at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.unpackFailureMessage(PackStreamMessageFormatV1.java:470) at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.read(PackStreamMessageFormatV1.java:431) at org.neo4j.driver.internal.net.SocketClient.receiveOne(SocketClient.java:196) at org.neo4j.driver.internal.net.SocketConnection.receiveOne(SocketConnection.java:217) at org.neo4j.driver.internal.net.ConcurrencyGuardingConnection.receiveOne(ConcurrencyGuardingConnection.java:165) at org.neo4j.driver.internal.net.pooling.PooledSocketConnection.receiveOne(PooledSocketConnection.java:183) at org.neo4j.driver.internal.InternalStatementResult.receiveOne(InternalStatementResult.java:335)
How-To
根據 neo4j 於 gitlab 上的說明: https://github.com/neo4j/neo4j/issues/4334
目前在 relation 的部分,尚未支援參數化傳遞。因此,根據需求,須將其拆成兩個 methods,建立兩種不同的 relationships
package neo4j.springdata.repository; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import neo4j.springdata.vo.User; @Repository public interface UserRepository extends CrudRepository<User, Long> { @Query(" match (from:User), (to:User) " + " where from.name={from} and to.name={to} " + " merge (from)-[:WORKS_WITH]->(to) ") void createWorksWithRelation(@Param("from") String from, @Param("to") String to); @Query(" match (from:User), (to:User) " + " where from.name={from} and to.name={to} " + " merge (from)-[:IS_FRIEND_OF]->(to) ") void createIsFriendOfRelation(@Param("from") String from, @Param("to") String to); }